区间更新,单点查询,,,,奇葩,HDU上强行加了扩栈才过。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 const int maxn = 50005; 10 struct edge 11 { 12 int v,next; 13 }e[maxn*2]; 14 int head[maxn],cnt,sum[maxn<<2],lazy[maxn<<2],val[maxn]; 15 int siz[maxn],son[maxn],fa[maxn],top[maxn],tid[maxn],dep[maxn],lable; 16 int n,m,p; 17 void init() 18 { 19 memset(head,-1,sizeof(head)); 20 memset(lazy,0,sizeof(lazy)); 21 memset(sum,0,sizeof(sum)); 22 cnt = lable = 0; 23 } 24 void add(int u,int v) 25 { 26 e[cnt].v = v; 27 e[cnt].next = head[u]; 28 head[u] = cnt++; 29 } 30 void find_heavy(int rt,int father,int depth) 31 { 32 fa[rt] = father; 33 siz[rt] = 1; 34 son[rt] = 0; 35 dep[rt] = depth; 36 int maxsize = 0; 37 for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father) 38 { 39 find_heavy(e[i].v,rt,depth+1); 40 siz[rt]+=siz[e[i].v]; 41 if(siz[rt]>maxsize) 42 maxsize = siz[rt],son[rt] = e[i].v; 43 } 44 } 45 void connect(int rt,int anc) 46 { 47 tid[rt] = ++lable; 48 top[rt] = anc; 49 if(son[rt])connect(son[rt],anc); 50 for(int i = head[rt];i!=-1;i = e[i].next) 51 if(e[i].v!=fa[rt]&&e[i].v!=son[rt]) 52 connect(e[i].v,e[i].v); 53 } 54 void pushup(int rt) 55 { 56 sum[rt] = sum[rt<<1]+sum[rt<<1|1]; 57 } 58 void pushdown(int rt,int m) 59 { 60 if(lazy[rt]) 61 { 62 lazy[rt<<1]+=lazy[rt]; 63 lazy[rt<<1|1]+=lazy[rt]; 64 sum[rt<<1]+=lazy[rt]*(m-(m>>1)); 65 sum[rt<<1|1]+=lazy[rt]*(m>>1); 66 lazy[rt] = 0; 67 } 68 } 69 void update(int L,int R,int v,int l,int r,int rt) 70 { 71 if(L<=l&&r<=R){ 72 lazy[rt]+=v; 73 sum[rt]+=v*(r-l+1); 74 return; 75 } 76 pushdown(rt,r-l+1); 77 int m = (l+r)>>1; 78 if(L<=m)update(L,R,v,lson); 79 if(m<R)update(L,R,v,rson); 80 pushup(rt); 81 } 82 void change(int x,int y,int c) 83 { 84 while(top[x]!=top[y]) 85 { 86 if(dep[top[x]]<dep[top[y]])swap(x,y); 87 update(tid[top[x]],tid[x],c,1,n,1); 88 x = fa[top[x]]; 89 } 90 if(dep[x]>dep[y])swap(x,y); 91 update(tid[x],tid[y],c,1,n,1); 92 } 93 int query(int L,int R,int l,int r,int rt) 94 { 95 if(L<=l&&r<=R)return sum[rt]; 96 pushdown(rt,r-l+1); 97 int m = (l+r)>>1,ret = 0; 98 if(L<=m)ret+=query(L,R,lson); 99 if(m<R)ret+=query(L,R,rson); 100 return ret; 101 } 102 int main() 103 { 104 //freopen("in.txt","r",stdin); 105 while(~scanf("%d%d%d",&n,&m,&p)) 106 { 107 for(int i = 1;i<=n;++i)scanf("%d",&val[i]); 108 init(); 109 for(int i = 1;i<=m;++i) 110 { 111 int u,v; 112 scanf("%d%d",&u,&v); 113 add(u,v);add(v,u); 114 } 115 find_heavy(1,1,1); 116 connect(1,1); 117 for(int i = 1;i<=n;++i)update(tid[i],tid[i],val[i],1,n,1); 118 while(p--) 119 { 120 char s[2];int a,b,c; 121 scanf("%s",s); 122 if(s[0]==‘I‘){ 123 scanf("%d%d%d",&a,&b,&c); 124 change(a,b,c); 125 } 126 else if(s[0]==‘D‘){ 127 scanf("%d%d%d",&a,&b,&c); 128 change(a,b,-c); 129 } 130 else{ 131 scanf("%d",&a); 132 printf("%d\n",query(tid[a],tid[a],1,n,1)); 133 } 134 } 135 } 136 return 0; 137 }
HDU3966 Aragorn's Story 树链剖分+线段树
时间: 2024-10-26 18:39:55