[SDOI2014]旅行
阿新 • • 發佈:2018-12-26
P3313 [SDOI2014]旅行
思路
有點噁心咯
每個信仰開一顆線段樹記錄
修改或者查詢的時候去那一顆信仰線段樹中查詢就好
必須動態開點線段樹
沒有區間修改還算好寫
錯誤
查詢跳鏈寫錯了
#include <bits/stdc++.h> #define FOR(i,a,b) for(int i=a;i<=b;++i) using namespace std; const int N=1e5+7; int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f; } vector<int> G[N]; int n,m,pj[N],xy[N]; int top[N],f[N],siz[N],idx[N],cnt,son[N],dep[N]; void dfs1(int u,int fa) { f[u]=fa; siz[u]=1; dep[u]=dep[fa]+1; for(vector<int>::iterator it=G[u].begin();it!=G[u].end();++it) { if(*it==fa) continue; dfs1(*it,u); siz[u]+=siz[*it]; if(siz[son[u]] < siz[*it]) son[u]=*it; } } void dfs2(int u,int topf) { idx[u]=++cnt; top[u]=topf; if(!son[u]) return; dfs2(son[u],topf); for(std::vector<int>::iterator it=G[u].begin();it!=G[u].end();++it) if(!idx[*it]) dfs2(*it,*it); } int rt[N]; namespace seg_tree{ #define ls e[rt].ch[0] #define rs e[rt].ch[1] struct node { int ch[2],ma,tot; }e[N*42]; int cnt; void pushup(int rt) { e[rt].ma=max(e[ls].ma,e[rs].ma); e[rt].tot=e[ls].tot+e[rs].tot; } void insert(int &rt,int L,int k,int l,int r) { if(!rt) rt=++cnt; if(l==r) {e[rt].ma=e[rt].tot=k;return;} int mid=(l+r)>>1; if(L<=mid) insert(ls,L,k,l,mid); else insert(rs,L,k,mid+1,r); pushup(rt); } int query_max(int L,int R,int l,int r,int rt) { if(!rt) return 0; if(L<=l&&r<=R) return e[rt].ma; int mid=(l+r)>>1,ans=0; if(L<=mid) ans=max(ans,query_max(L,R,l,mid,ls)); if(R>mid) ans=max(ans,query_max(L,R,mid+1,r,rs)); return ans; } int query_tot(int L,int R,int l,int r,int rt) { if(!rt) return 0; if(L<=l&&r<=R) return e[rt].tot; int mid=(l+r)>>1,ans=0; if(L<=mid) ans+=query_tot(L,R,l,mid,ls); if(R>mid) ans+=query_tot(L,R,mid+1,r,rs); return ans; } } int Query_Sum(int x,int y) { int ans=0,tmp=xy[x]; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=seg_tree::query_tot(idx[top[x]],idx[x],1,n,rt[tmp]); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); ans+=seg_tree::query_tot(idx[x],idx[y],1,n,rt[tmp]); return ans; } int Query_Max(int x,int y) { int ans=0,tmp=xy[x]; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=max(seg_tree::query_max(idx[top[x]],idx[x],1,n,rt[tmp]),ans); x=f[top[x]]; } if(dep[x]>dep[y]) swap(x,y); ans=max(seg_tree::query_max(idx[x],idx[y],1,n,rt[tmp]),ans); return ans; } int main() { n=read(),m=read(); FOR(i,1,n) pj[i]=read(),xy[i]=read(); FOR(i,2,n) { int x=read(),y=read(); G[x].push_back(y),G[y].push_back(x); } dfs1(1,0); dfs2(1,1); FOR(i,1,n) seg_tree::insert(rt[xy[i]],idx[i],pj[i],1,n); FOR(i,1,m) { char s[10]; scanf("%s",s); int x=read(),y=read(); if(s[0]=='C'&&s[1]=='C') { seg_tree::insert(rt[xy[x]],idx[x],0,1,n); xy[x]=y; seg_tree::insert(rt[xy[x]],idx[x],pj[x],1,n); } else if(s[0]=='C'&&s[1]=='W') { pj[x]=y; seg_tree::insert(rt[xy[x]],idx[x],pj[x],1,n); } else if(s[0]=='Q'&&s[1]=='S') { printf("%d\n",Query_Sum(x,y)); } else {//OK printf("%d\n",Query_Max(x,y)); } } return 0; }