标签:
3 2 5 1 2 3 2 1 2 3 I 1 3 5 Q 2 D 1 2 2 Q 1 Q 3
7 4 8Hint1.The number of enemies may be negative. 2.Huge input, be careful.
瞬秒一A~~
题目大意:一个图,每个点都有点权,3种操作,I a b,a到b的点点权加一个值,D是减一个值,Q是查询这个点的点权
网上大都是树链剖分写的,提交了俩发现速度并不比我的快,,真的不知道前边300多毫秒的咋写的
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> #define INF 0x7fffffff #define max(a,b) (a>b?a:b) using namespace std; int vis[50050]; struct LCT { int bef[50050],pre[50050],next[50050][2],key[50050],add[50050]; void init() { memset(pre,0,sizeof(pre)); memset(next,0,sizeof(next)); memset(key,0,sizeof(key)); memset(add,0,sizeof(add)); } void pushdown(int x) { if(add[x]) { int a,b; a=next[x][0]; b=next[x][1]; if(a)//不用加,实际上,同下边那个b<span id="transmark"></span> { add[a]+=add[x]; key[a]+=add[x]; } if(b) { add[b]+=add[x]; key[b]+=add[x]; } add[x]=0; } } void rotate(int x,int kind) { int y,z; y=pre[x]; z=pre[y]; pushdown(y); pushdown(x); next[y][!kind]=next[x][kind]; pre[next[x][kind]]=y; next[z][next[z][1]==y]=x; pre[x]=z; next[x][kind]=y; pre[y]=x; } void splay(int x) { int rt; for(rt=x;pre[rt];rt=pre[rt]); if(x!=rt) { bef[x]=bef[rt]; bef[rt]=0; pushdown(x); while(pre[x]) { if(next[pre[x]][0]==x) { rotate(x,1); } else rotate(x,0); } } } void access(int x) { int fa; for(fa=0;x;x=bef[x]) { splay(x); pushdown(x); pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=fa; pre[fa]=x; bef[fa]=0; fa=x; } } void change(int x,int y,int val) { access(y); for(y=0;x;x=bef[x]) { splay(x); if(!bef[x]) { key[x]+=val; key[y]+=val; key[next[x][1]]+=val; add[next[x][1]]+=val; add[y]+=val; return; } pushdown(x); pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=y; pre[y]=x; bef[y]=0; y=x; } } int query(int x) { splay(x); return key[x]; } }lct; struct s { int u,v,next; }edge[100020<<1]; int head[100020],cnt; void add(int u,int v) { edge[cnt].u=u; edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } void bfs(int u) { queue<int>q; memset(vis,0,sizeof(vis)); vis[u]=1; q.push(u); while(!q.empty()) { u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!vis[v]) { lct.bef[v]=u; vis[v]=1; q.push(v); } } } } int main() { int n,m,q; while(scanf("%d%d%d",&n,&m,&q)!=EOF) { int i; lct.init(); cnt=0; memset(head,-1,sizeof(head)); for(i=1;i<=n;i++) { scanf("%d",&lct.key[i]); } for(i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } bfs(1); while(q--) { char op[2]; scanf("%s",op); if(op[0]=='I') { int x,y,val; scanf("%d%d%d",&x,&y,&val); lct.change(x,y,val); } else if(op[0]=='D') { int x,y,val; scanf("%d%d%d",&x,&y,&val); lct.change(x,y,-val); } else if(op[0]=='Q') { int x; scanf("%d",&x); printf("%d\n",lct.query(x)); } } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDOJ 题目3966 Aragorn's Story(Link Cut Tree成段加减点权,查询点权)
标签:
原文地址:http://blog.csdn.net/yu_ch_sh/article/details/47983577