Jzoj3625 旅行(travel)

来源:互联网 发布:考勤机数据恢复 编辑:程序博客网 时间:2024/06/03 22:41

非常好的树剖模板题了,直接C颗线段树上去就好了,动态开点一次写对~

#pragma GCC opitmize("O3")#pragma G++ opitmize("O3")#include<stdio.h>#include<string.h>#include<algorithm>#define N 100010#define mid (l+r>>1)using namespace std;struct edge{ int v,nt; } G[200010];struct nod{ int l,r,s,m; } s[3000010];int h[N],sz[N],top[N],son[N],f[N],d[N];int n,m,cnt=1,tot=0,clk=0,w[N],l[N],c[N],rt[N];inline void gmax(int& x,int y){ x<y?x=y:0; }inline void ps(nod& x){x.s=s[x.l].s+s[x.r].s;x.m=max(s[x.l].m,s[x.r].m);}inline void adj(int x,int y){ G[++cnt]=(edge){y,h[x]}; h[x]=cnt;G[++cnt]=(edge){x,h[y]}; h[y]=cnt;}void dfs(int x,int p){d[x]=d[p]+1; sz[x]=1; f[x]=p;for(int v,i=h[x];i;i=G[i].nt)if(!d[v=G[i].v]){dfs(v,x); sz[x]+=sz[v];if(sz[v]>sz[son[x]]) son[x]=v;}}void dgs(int x,int p){top[x]=p; l[x]=++clk;if(son[x]) dgs(son[x],p);for(int v,i=h[x];i;i=G[i].nt)if(!l[v=G[i].v]) dgs(v,v);}void insert(int l,int r,int& x,int p,int k){if(!x) x=++tot;if(l==r) { s[x].s=s[x].m=k; return; }if(p<=mid) insert(l,mid,s[x].l,p,k);else insert(mid+1,r,s[x].r,p,k);ps(s[x]);}void remove(int l,int r,int& x,int p){if(l==r){ x=0; return; }if(p<=mid) remove(l,mid,s[x].l,p);else remove(mid+1,r,s[x].r,p);if(s[x].l || s[x].r) ps(s[x]); else x=0;}void modify(int l,int r,int x,int p,int k){if(l==r){ s[x].s=s[x].m=k; return; }if(p<=mid) modify(l,mid,s[x].l,p,k);else modify(mid+1,r,s[x].r,p,k);ps(s[x]);}int queryS(int l,int r,int x,int L,int R){if(!x) return 0;if(L<=l && r<=R) return s[x].s;int ans=0;if(L<=mid) ans+=queryS(l,mid,s[x].l,L,R);if(mid<R) ans+=queryS(mid+1,r,s[x].r,L,R);return ans;}int gSum(int x,int y){int ans=0,C=c[x];for(;top[x]!=top[y];y=f[top[y]]){if(d[top[x]]>d[top[y]]) swap(x,y);ans+=queryS(1,n,rt[C],l[top[y]],l[y]);}if(d[x]>d[y]) swap(x,y);return ans+queryS(1,n,rt[C],l[x],l[y]);}int queryM(int l,int r,int x,int L,int R){if(!x) return 0;if(L<=l && r<=R) return s[x].m;int ans=0;if(L<=mid) gmax(ans,queryM(l,mid,s[x].l,L,R));if(mid<R) gmax(ans,queryM(mid+1,r,s[x].r,L,R));return ans;}int gMax(int x,int y){int ans=0,C=c[x];for(;top[x]!=top[y];y=f[top[y]]){if(d[top[x]]>d[top[y]]) swap(x,y);gmax(ans,queryM(1,n,rt[C],l[top[y]],l[y]));}if(d[x]>d[y]) swap(x,y);return max(ans,queryM(1,n,rt[C],l[x],l[y]));}int main(){freopen("travel.in","r",stdin);freopen("travel.out","w",stdout); scanf("%d%d",&n,&m);for(int i=1;i<=n;++i) scanf("%d%d",w+i,c+i);for(int x,y,i=1;i<n;++i) scanf("%d%d",&x,&y),adj(x,y); dfs(1,0); dgs(1,1); char o[3];for(int i=1;i<=n;++i) insert(1,n,rt[c[i]],l[i],w[i]);for(int x,y;m--;){scanf("%s%d%d",o,&x,&y);if(*o=='C'){if(o[1]=='C'){remove(1,n,rt[c[x]],l[x]);insert(1,n,rt[y],l[x],w[x]);c[x]=y;} else {modify(1,n,rt[c[x]],l[x],y);w[x]=y;}} else {if(o[1]=='S') printf("%d\n",gSum(x,y));else printf("%d\n",gMax(x,y));}}}

原创粉丝点击