Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12479 Accepted Submission(s):
3331
1 #pragma comment(linker, "/STACK:1024000000,1024000000") //据说这玩意可以手动扩栈 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdlib> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <iostream> 10 #include "algorithm" 11 #define mem(a,b) memset(a,b,sizeof(a)) 12 using namespace std; 13 typedef long long LL; 14 const int MAX=50005; 15 int n,m,T; 16 int tot,ttt; 17 int head[MAX],adj[MAX<<2],nex[MAX<<2]; 18 int a[MAX],deep[MAX],fa[MAX]; 19 int siz[MAX],son[MAX],top[MAX],tid[MAX],rak[MAX]; 20 void addedge(int u,int v){ 21 tot++; 22 adj[tot]=v; 23 nex[tot]=head[u]; 24 head[u]=tot; 25 } 26 void init(){ 27 int i,j; 28 mem(head,0),mem(son,0); 29 tot=ttt=0; 30 } 31 void dfs1(int x,int ff,int de){ //标父亲,后代个数(包括自己),深度,重儿子 32 int i,j; 33 deep[x]=de; 34 siz[x]=1;fa[x]=ff; 35 for (i=head[x];i;i=nex[i]){ 36 int v=adj[i]; 37 if (v==ff) continue; 38 dfs1(v,x,de+1); 39 siz[x]+=siz[v]; 40 if (!son[x] || siz[v]>siz[son[x]]){ 41 son[x]=v; 42 } 43 } 44 } 45 void dfs2(int x,int tp){//编号,拆树 46 int i,j; 47 top[x]=tp; 48 tid[x]=++ttt; 49 rak[tid[ttt]]=x; 50 if (!son[x]) return; 51 dfs2(son[x],tp); 52 for (i=head[x];i;i=nex[i]){ 53 if (adj[i]!=son[x] && adj[i]!=fa[x]){ 54 dfs2(adj[i],adj[i]); 55 } 56 } 57 } 58 //线段树 59 #define lson rt<<1,l,m 60 #define rson rt<<1|1,m+1,r 61 int sum[MAX<<2],la[MAX<<2]; 62 63 void PushUp(int rt){ 64 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 65 } 66 void PushDown(int rt,int l,int r){ 67 if (la[rt]){ 68 int m=(l+r)>>1; 69 la[rt<<1]+=la[rt];la[rt<<1|1]+=la[rt]; 70 sum[rt<<1]+=(m-l+1)*la[rt]; 71 sum[rt<<1|1]+=(r-m)*la[rt]; 72 la[rt]=0; 73 } 74 } 75 void build(int rt,int l,int r){ 76 la[rt]=0; 77 if(l==r){ 78 sum[rt]=a[rak[l]]; 79 return; 80 } 81 int m=(l+r)>>1; 82 build(lson); 83 build(rson); 84 PushUp(rt); 85 } 86 void update(int rt,int l,int r,int x,int y,int z){ 87 if (x<=l && r<=y){ 88 sum[rt]+=z*(r-l+1); 89 la[rt]+=z; 90 return; 91 } 92 int m=(l+r)>>1; 93 PushDown(rt,l,r); 94 if (x<=m) update(lson,x,y,z); 95 if (y>m) update(rson,x,y,z); 96 PushUp(rt); 97 } 98 int search(int rt,int l,int r,int x){ 99 if (l==r){ 100 return sum[rt]; 101 } 102 int res=0; 103 int m=(l+r)>>1; 104 PushDown(rt,l,r); 105 if (x<=m) res+=search(lson,x); 106 if (x>m) res+=search(rson,x); 107 PushUp(rt); 108 return res; 109 } 110 void calc(int x,int y,int z){ 111 int i,j; 112 while (top[x]!=top[y]){ 113 if (deep[x]<deep[y]) swap(x,y); 114 update(1,1,n,tid[top[x]],tid[x],z); 115 x=fa[top[x]]; 116 } 117 if (deep[x]>deep[y]) swap(x,y); 118 update(1,1,n,tid[x],tid[y],z); 119 } 120 int main(){ 121 freopen ("story.in","r",stdin); 122 freopen ("story.out","w",stdout); 123 int i,j; 124 int u,v,x,y,z; 125 char c; 126 while (~scanf("%d%d%d",&n,&m,&T)){ 127 init(); 128 for (i=1;i<=n;i++){ 129 scanf("%d",a+i); 130 } 131 for (i=1;i<=m;i++){ 132 scanf("%d%d\n",&u,&v); 133 addedge(u,v); 134 addedge(v,u); 135 } 136 dfs1(1,0,1); 137 dfs2(1,1); 138 build(1,1,n); 139 while (T--){ 140 c=getchar();//cout<<c<<endl; 141 if (c==‘Q‘){ 142 scanf("%d\n",&x); 143 printf("%d\n",search(1,1,n,tid[x])); 144 } 145 else{ 146 scanf("%d%d%d\n",&x,&y,&z); 147 if (c==‘D‘) z=-z; 148 calc(x,y,z); 149 } 150 } 151 } 152 return 0; 153 }
HDU-3966 Aragorn's Story(树链剖分+线段树)
原文:http://www.cnblogs.com/keximeiruguo/p/7349906.html