Bzoj3531:[Sdoi2014]旅行:树链剖分+动态开点线段树

来源:互联网 发布:文章校对软件 编辑:程序博客网 时间:2024/05/16 08:11

题目链接:[Sdoi2014]旅行

对于每种颜色维护一颗线段树,为了节约空间这里我们动态开点

然后就是弱鸡的线段树操作了

指针的动态开点线段树现在才会写……

#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>using namespace std;const int maxn=100010;const int maxc=100001;int n,m,tot=0,h[maxn],s[maxn],ind=0;struct edge{int to,next;}G[maxn<<1];int pos[maxn],Belong[maxn],dep[maxn];int ret,w[maxn],c[maxn],fa[maxn];char str[10];struct seg{seg *lc,*rc;int s,mx;seg():lc(0x0),rc(0x0),s(0),mx(0){}};seg *root[maxn];void add(int x,int y){G[++tot].to=y;G[tot].next=h[x];h[x]=tot;}void dfs1(int x){s[x]=1; dep[x]=dep[fa[x]]+1;for (int i=h[x];i;i=G[i].next){int v=G[i].to;if (v==fa[x]) continue;fa[v]=x; dfs1(v); s[x]+=s[v]; }}void dfs2(int x,int L){pos[x]=++ind; int k=0; Belong[x]=L;for (int i=h[x];i;i=G[i].next)if (s[G[i].to]>s[k]&&dep[G[i].to]>dep[x]) k=G[i].to;if (!k) return; dfs2(k,L);for (int i=h[x];i;i=G[i].next)if (dep[G[i].to]>dep[x]&&k!=G[i].to) dfs2(G[i].to,G[i].to); }void push_up(seg *p){p->s=p->mx=0;p->s+=p->lc?p->lc->s:0;p->s+=p->rc?p->rc->s:0;p->mx=p->lc?p->lc->mx:0;p->mx=max(p->mx,p->rc?p->rc->mx:0);}void update(seg *&p,int L,int R,int l,int r,int val){if (!p) p=new seg();if (l<=L&&R<=r){p->s=p->mx=val;return;}int mid=(L+R)>>1;if (l<mid) update(p->lc,L,mid,l,r,val);if (mid<r) update(p->rc,mid,R,l,r,val);push_up(p);}void ask_mx(seg *p,int L,int R,int l,int r){if (!p) return;if (l<=L&&R<=r){ret=max(ret,p->mx);return;}int mid=(L+R)>>1;if (l<mid) ask_mx(p->lc,L,mid,l,r);if (mid<r) ask_mx(p->rc,mid,R,l,r);}int query_mx(int x,int y,int col){int mx=0;while (Belong[x]!=Belong[y]){if (dep[Belong[x]]<dep[Belong[y]]) swap(x,y);ret=0; ask_mx(root[col],1,n+1,pos[Belong[x]],pos[x]+1);mx=max(mx,ret); x=fa[Belong[x]];}if (dep[x]<dep[y]) swap(x,y);ret=0; ask_mx(root[col],1,n+1,pos[y],pos[x]+1);mx=max(mx,ret); return mx;}void ask_s(seg *p,int L,int R,int l,int r){if (!p) return;if (l<=L&&R<=r){ret+=p->s;return;}int mid=(L+R)>>1;if (l<mid) ask_s(p->lc,L,mid,l,r);if (mid<r) ask_s(p->rc,mid,R,l,r);}int query_s(int x,int y,int col){int ans=0;while (Belong[x]!=Belong[y]){if (dep[Belong[x]]<dep[Belong[y]]) swap(x,y);ret=0; ask_s(root[col],1,n+1,pos[Belong[x]],pos[x]+1);ans+=ret; x=fa[Belong[x]];}if (dep[x]<dep[y]) swap(x,y);ret=0; ask_s(root[col],1,n+1,pos[y],pos[x]+1);ans+=ret; return ans;}int main(){scanf("%d%d",&n,&m);for (int i=1;i<=n;++i) scanf("%d%d",&w[i],&c[i]);for (int i=1;i<n;++i){int x,y; scanf("%d%d",&x,&y);add(x,y); add(y,x);}dfs1(1); dfs2(1,1);for (int i=1;i<=n;++i) update(root[c[i]],1,n+1,pos[i],pos[i]+1,w[i]);for (int i=1;i<=m;++i){scanf("%s",str+1);if (str[1]=='C'){if (str[2]=='C'){int x,y; scanf("%d%d",&x,&y);update(root[c[x]],1,n+1,pos[x],pos[x]+1,0);c[x]=y;update(root[c[x]],1,n+1,pos[x],pos[x]+1,w[x]);}else if (str[2]=='W'){int x,y; scanf("%d%d",&x,&y);w[x]=y; update(root[c[x]],1,n+1,pos[x],pos[x]+1,w[x]);}}else if (str[1]=='Q'){if (str[2]=='S'){int x,y;scanf("%d%d",&x,&y);printf("%d\n",query_s(x,y,c[x]));}else {int x,y;scanf("%d%d",&x,&y);printf("%d\n",query_mx(x,y,c[x]));}}}}


1 0
原创粉丝点击