hdu5044 树链剖分模板(点+边,区间修改)+(附带输入优化和申请栈)
这是常规的使用线段树超时:
1 #pragma comment(linker, "/STACK:16777216") 2 #include<stdio.h> 3 #include<string.h> 4 long long ans[2][100005]; 5 int next[200005],head[100005],point[200005]; 6 int num[100005],father[100005],son[100005],deep[100005],top[100005],tree[100005],pre[100005]; 7 long long setv[2][400005]; 8 int now,cnt; 9 void add(int x,int y) 10 { 11 next[++now]=head[x]; 12 head[x]=now; 13 point[now]=y; 14 } 15 void dfs1(int u) 16 { 17 num[u]=1; 18 for (int i=head[u];i!=-1;i=next[i]) 19 { 20 int v=point[i]; 21 if (v==father[u]) continue; 22 father[v]=u; 23 deep[v]=deep[u]+1; 24 dfs1(v); 25 num[u]+=num[v]; 26 if (son[u]==-1||num[son[u]]<num[v]) son[u]=v; 27 } 28 } 29 void dfs2(int u,int lead) 30 { 31 top[u]=lead; 32 tree[u]=++cnt; 33 pre[cnt]=u; 34 if (son[u]==-1) return; 35 dfs2(son[u],lead); 36 for (int i=head[u];i!=-1;i=next[i]) 37 { 38 int v=point[i]; 39 if (father[u]!=v&&son[u]!=v) dfs2(v,v); 40 } 41 } 42 void update(int o,int l,int r,int kind,int y1,int y2,long long d) 43 { 44 if (y1<=l&&y2>=r) { 45 setv[kind][o]+=d; 46 return; 47 } 48 if (setv[kind][o]!=0) 49 { 50 setv[kind][o*2]+=setv[kind][o]; 51 setv[kind][o*2+1]+=setv[kind][o]; 52 setv[kind][o]=0; 53 } 54 int mid=l+(r-l)/2; 55 if (y1<=mid) update(o*2,l,mid,kind,y1,y2,d); 56 if (y2>mid) update(o*2+1,mid+1,r,kind,y1,y2,d); 57 } 58 //int query(int o,int l,int r,int kind,int y) 59 void query(int o,int l,int r) 60 { 61 if (l==r) {ans[0][pre[l]]=setv[0][o]; ans[1][pre[l]]=setv[1][o]; return; } 62 if (setv[0][o]!=0) 63 { 64 setv[0][o*2]+=setv[0][o]; 65 setv[0][o*2+1]+=setv[0][o]; 66 setv[0][o]=0; 67 } 68 if (setv[1][o]!=0) 69 { 70 setv[1][o*2]+=setv[1][o]; 71 setv[1][o*2+1]+=setv[1][o]; 72 setv[1][o]=0; 73 } 74 int mid=l+(r-l)/2; 75 query(o*2,l,mid); 76 query(o*2+1,mid+1,r); 77 } 78 void change(int kind,int l,int r,long long d) 79 { 80 int temp; 81 while (top[l]!=top[r]) 82 { 83 if (deep[top[l]]<deep[top[r]]) {temp=l; l=r; r=temp; } 84 update(1,1,cnt,kind,tree[top[l]],tree[l],d); 85 l=father[top[l]]; 86 } 87 if (deep[l]>deep[r]) {temp=l; l=r; r=temp; } 88 if (kind==0) update(1,1,cnt,kind,tree[l],tree[r],d); 89 else update(1,1,cnt,kind,tree[son[l]],tree[r],d); 90 } 91 void scanf ( int& x , char c = 0 , int flag = 0 ) { 92 while ( ( c = getchar () ) != '-' && ( c < '0' || c > '9' ) ) ; 93 if ( c == '-' ) flag = 1 , x = 0 ; 94 else x = c - '0' ; 95 while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ; 96 if ( flag ) x = -x ; 97 } 98 int main() 99 { 100 int T,t,i,x,y,d,l,r,n,m; 101 char s[5]; 102 scanf("%d",&T); 103 for (t=1;t<=T;t++) 104 { 105 now=0; cnt=0; 106 memset(head,-1,sizeof(head)); 107 memset(son,-1,sizeof(son)); 108 memset(setv,0,sizeof(setv)); 109 deep[1]=1; father[1]=1; 110 scanf("%d%d",&n,&m); 111 for (i=1;i<n;i++) 112 { 113 scanf(x); scanf(y); 114 add(x,y); add(y,x); 115 } 116 dfs1(1); dfs2(1,1); 117 for (i=1;i<=m;i++) 118 { 119 scanf("%s",s); 120 scanf(l); scanf(r); scanf(d); 121 if (s[3]=='1') change(0,l,r,d); 122 else change(1,l,r,d); 123 } 124 printf("Case #%d:\n",t); 125 query(1,1,cnt); 126 for (i=1;i<n;i++) printf("%I64d ",ans[0][i]); printf("%I64d\n",ans[0][n]); 127 for (i=2;i<=n-1;i++) printf("%I64d ",ans[1][i]); 128 if (n==1) printf("\n"); else printf("%I64d\n",ans[1][n]); 129 } 130 }
因为是单次查询全部,所以可以累加变量,快了许多:
1 #pragma comment(linker, "/STACK:16777216") 2 #include<stdio.h> 3 #include<string.h> 4 long long ans[2][100005]; 5 int n; 6 int next[200005],head[100005],point[200005]; 7 int num[100005],father[100005],son[100005],deep[100005],top[100005],tree[100005],pre[100005]; 8 long long setv[2][200005]; 9 int now,cnt; 10 void add(int x,int y) 11 { 12 next[++now]=head[x]; 13 head[x]=now; 14 point[now]=y; 15 } 16 void dfs1(int u) 17 { 18 num[u]=1; 19 for (int i=head[u];i!=-1;i=next[i]) 20 { 21 int v=point[i]; 22 if (v==father[u]) continue; 23 father[v]=u; 24 deep[v]=deep[u]+1; 25 dfs1(v); 26 num[u]+=num[v]; 27 if (son[u]==-1||num[son[u]]<num[v]) son[u]=v; 28 } 29 } 30 void dfs2(int u,int lead) 31 { 32 top[u]=lead; 33 tree[u]=++cnt; 34 pre[cnt]=u; 35 if (son[u]==-1) return; 36 dfs2(son[u],lead); 37 for (int i=head[u];i!=-1;i=next[i]) 38 { 39 int v=point[i]; 40 if (father[u]!=v&&son[u]!=v) dfs2(v,v); 41 } 42 } 43 void query() 44 { 45 long long t1=0,t2=0; 46 for (int i=1;i<=n;i++) 47 { 48 t1+=setv[0][i]; ans[0][pre[i]]=t1; 49 t2+=setv[1][i]; ans[1][pre[i]]=t2; 50 } 51 } 52 void change(int kind,int l,int r,long long d) 53 { 54 int temp; 55 while (top[l]!=top[r]) 56 { 57 if (deep[top[l]]<deep[top[r]]) {temp=l; l=r; r=temp; } 58 setv[kind][tree[top[l]]]+=d; setv[kind][tree[l]+1]-=d; 59 //update(1,1,cnt,kind,tree[top[l]],tree[l],d); 60 l=father[top[l]]; 61 } 62 if (deep[l]>deep[r]) {temp=l; l=r; r=temp; } 63 if (kind==0) {setv[0][tree[l]]+=d; setv[0][tree[r]+1]-=d;} 64 else {setv[1][tree[son[l]]]+=d; setv[1][tree[r]+1]-=d;} 65 } 66 void scanf ( int& x , char c = 0 , int flag = 0 ) { 67 while ( ( c = getchar () ) != '-' && ( c < '0' || c > '9' ) ) ; 68 if ( c == '-' ) flag = 1 , x = 0 ; 69 else x = c - '0' ; 70 while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ; 71 if ( flag ) x = -x ; 72 } 73 int main() 74 { 75 int T,t,i,x,y,d,l,r,m; 76 char s[5]; 77 scanf("%d",&T); 78 for (t=1;t<=T;t++) 79 { 80 now=0; cnt=0; 81 memset(head,-1,sizeof(head)); 82 memset(son,-1,sizeof(son)); 83 memset(setv,0,sizeof(setv)); 84 deep[1]=1; father[1]=1; 85 scanf("%d%d",&n,&m); 86 for (i=1;i<n;i++) 87 { 88 scanf(x); scanf(y); 89 add(x,y); add(y,x); 90 } 91 dfs1(1); dfs2(1,1); 92 for (i=1;i<=m;i++) 93 { 94 scanf("%s",s); 95 scanf(l); scanf(r); scanf(d); 96 if (s[3]=='1') change(0,l,r,d); 97 else change(1,l,r,d); 98 } 99 printf("Case #%d:\n",t); 100 query(); 101 for (i=1;i<n;i++) printf("%I64d ",ans[0][i]); printf("%I64d\n",ans[0][n]); 102 for (i=2;i<=n-1;i++) printf("%I64d ",ans[1][i]); 103 if (n==1) printf("\n"); else printf("%I64d\n",ans[1][n]); 104 } 105 }