传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3052
题目大意:自己看看,懒得写
题解:带修改的树上莫队,经典爆评测机的题
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #define maxn 100100 7 #define ll long long 8 using namespace std; 9 int n,m,q,blo; 10 ll ans; 11 int tot,top,totc,totq,lydsytime,belong; 12 int bin[20],deep[maxn],fa[maxn][20],dfn[maxn]; 13 int z[maxn]; 14 int num[maxn]; 15 int now[maxn],v[maxn*2],pre[maxn*2]; 16 int pos[maxn]; 17 ll res[maxn],val[maxn],c[maxn],cpre[maxn],w[maxn]; 18 bool vis[maxn]; 19 struct data{ 20 int x,y,t,id; 21 ll pre; 22 }cg[maxn],bg[maxn]; 23 int read() 24 { 25 int x=0; char ch; bool bo=0; 26 while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1; 27 while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); 28 if (bo) return -x; return x; 29 } 30 bool cmp(data a,data b) 31 { 32 if (pos[a.x]==pos[b.x]) return dfn[a.y]<dfn[b.y]; return pos[a.x]<pos[b.x]; 33 } 34 void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; 35 } 36 void prework(){ 37 bin[0]=1; 38 for (int i=1; i<=20; i++) bin[i]=bin[i-1]*2; 39 } 40 int dfs(int x) 41 { 42 int size=0; 43 dfn[x]=++lydsytime; 44 for (int i=1; i<=16; i++) 45 if (deep[x]>=bin[i]) 46 fa[x][i]=fa[fa[x][i-1]][i-1]; 47 else 48 break; 49 for (int p=now[x]; p; p=pre[p]) 50 { 51 int son=v[p]; 52 if (son==fa[x][0]) continue; 53 deep[son]=deep[x]+1; 54 fa[son][0]=x; 55 size+=dfs(son); 56 if (size>blo) 57 { 58 belong++; 59 for (int i=1; i<=blo; i++) pos[z[top--]]=belong; 60 size=0; 61 } 62 } 63 z[++top]=x; 64 return size+1; 65 } 66 int lca(int x,int y) 67 { 68 // cout<<" pre "<<x<<" "<<y<<endl; 69 if (deep[x]<deep[y]) swap(x,y); 70 int t=deep[x]-deep[y]; 71 for (int i=0; bin[i]<=t; i++) 72 if (bin[i]&t) 73 x=fa[x][i]; 74 for (int i=17; i>=0; i--) 75 if (fa[x][i]!=fa[y][i]) 76 x=fa[x][i], y=fa[y][i]; 77 // cout<<" now "<<x<<" "<<y<<endl; 78 if (x==y) return x; 79 return fa[x][0]; 80 } 81 void reverse(int x) 82 { 83 //cout<<" re "<<x<<" "<<c[x]<<" "<<val[c[x]]<<" "<<num[c[x]]<<" "<<w[num[c[x]]+1]<<" "<<w[1]<<endl; 84 if (vis[x]) ans-=val[c[x]]*w[num[c[x]]],num[c[x]]--; 85 else num[c[x]]++,ans+=val[c[x]]*w[num[c[x]]]; 86 vis[x]^=1; 87 } 88 void work(int u,int v) 89 { 90 //cout<<" pre u v "<<u<<" "<<v<<endl; 91 while (u!=v) 92 { 93 if (deep[u]>deep[v]) 94 { 95 reverse(u); 96 u=fa[u][0]; 97 } 98 else 99 { 100 reverse(v); 101 v=fa[v][0]; 102 } 103 //cout<<" now u v "<<u<<" "<<v<<" "<<endl; 104 } 105 } 106 void change(int x,int y) 107 { 108 if (vis[x]) 109 { 110 reverse(x); 111 c[x]=y; 112 reverse(x); 113 } 114 else c[x]=y; 115 } 116 void init() 117 { 118 n=read(); m=read(); q=read(); 119 blo=pow(n,2.0/3)*0.5; 120 for (int i=1; i<=m; i++) val[i]=read(); 121 for (int i=1; i<=n; i++) w[i]=read(); 122 for (int i=1; i<n; i++) 123 { 124 int u=read(),v=read(); 125 ins(u,v); ins(v,u); 126 } 127 dfs(1); 128 //for (int i=1; i<=n; i++) cout<<" dsdsd "<<fa[i][0]<<" "<<dfn[i]<<endl; 129 belong++; 130 while (top) pos[z[top--]]=belong; 131 for (int i=1; i<=n; i++) c[i]=cpre[i]=read(); 132 for (int i=1; i<=q; i++) 133 { 134 int type=read(),x=read(),y=read(); 135 if (!type) 136 { 137 totc++; cg[totc].x=x,cg[totc].y=y,cg[totc].pre=cpre[x],cpre[x]=y; 138 } 139 else 140 { 141 totq++; bg[totq].x=x,bg[totq].y=y,bg[totq].t=totc; bg[totq].id=totq; 142 } 143 } 144 sort(bg+1,bg+totq+1,cmp); 145 /*for (int i=1; i<=totq; i++) 146 { 147 cout<<" "<<bg[i].x<<" "<<bg[i].y<<" "<<bg[i].t<<" "<<endl; 148 }*/ 149 } 150 void solve() 151 { 152 for (int i=1; i<=bg[1].t; i++) change(cg[i].x,cg[i].y); 153 work(bg[1].x,bg[1].y); 154 int t=lca(bg[1].x,bg[1].y); 155 //cout<<" "<<t<<" "<<bg[1].x<<" "<<bg[1].y<<endl; 156 reverse(t); res[bg[1].id]=ans; reverse(t); 157 for (int i=2; i<=totq; i++) 158 { 159 for (int j=bg[i-1].t+1; j<=bg[i].t; j++) 160 change(cg[j].x,cg[j].y); 161 for (int j=bg[i-1].t+1; j>bg[i].t; j--) 162 change(cg[j].x,cg[j].pre); 163 work(bg[i-1].x,bg[i].x); work(bg[i-1].y,bg[i].y); 164 int t=lca(bg[i].x,bg[i].y); 165 reverse(t); res[bg[i].id]=ans; reverse(t); 166 } 167 } 168 int main() 169 { 170 prework(); 171 init(); 172 solve(); 173 for (int i=1; i<=totq; i++) 174 printf("%lld ",res[i]); 175 } 176 /* 177 4 3 5 178 1 9 2 179 7 6 5 1 180 2 3 181 3 1 182 3 4 183 1 2 3 2 184 1 1 2 185 1 4 2 186 0 2 1 187 1 1 2 188 1 4 2 189 */
一次CE,一次WA,一次AC
-------------哦,对了这道题还是有个坑,就是怎么推出带修改的树上莫队时间复杂度!待zfy来教我补!