[luogu P3313] [SDOI2014]旅行
题目描述
S国有N个城市,编号从1到N。城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市。每个城市信仰不同的宗教,如飞天面条神教、隐形独角兽教、绝地教都是常见的信仰。
为了方便,我们用不同的正整数代表各种宗教, S国的居民常常旅行。旅行时他们总会走最短路,并且为了避免麻烦,只在信仰和他们相同的城市留宿。当然旅程的终点也是信仰与他相同的城市。S国政府为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值。
在S国的历史上常会发生以下几种事件:
“CC x c“:城市x的居民全体改信了c教;
“CW x w“:城市x的评级调整为w;
“QS x y“:一位旅行者从城市x出发,到城市y,并记下了途中留宿过的城市的评级总和;
“QM x y“:一位旅行者从城市x出发,到城市y,并记下了途中留宿过的城市的评级最大值。
由于年代久远,旅行者记下的数字已经遗失了,但记录开始之前每座城市的信仰与评级,还有事件记录本身是完好的。请根据这些信息,还原旅行者记下的数字。 为了方便,我们认为事件之间的间隔足够长,以致在任意一次旅行中,所有城市的评级和信仰保持不变。
输入输出格式
输入格式:
输入的第一行包含整数N,Q依次表示城市数和事件数。 接下来N行,第i+l行两个整数Wi,Ci依次表示记录开始之前,城市i的评级和信仰。 接下来N-1行每行两个整数x,y表示一条双向道路。 接下来Q行,每行一个操作,格式如上所述。
输出格式:
对每个QS和QM事件,输出一行,表示旅行者记下的数字。
输入输出样例
输入样例#1: 复制
5 6 3 1 2 3 1 2 3 3 5 1 1 2 1 3 3 4 3 5 QS 1 5 CC 3 1 QS 1 5 CW 3 3 QS 1 5 QM 2 4输出样例#1: 复制
8 9 113说明
N,Q < =10^5 , C < =10^5
数据保证对所有QS和QM事件,起点和终点城市的信仰相同;在任意时
刻,城市的评级总是不大于10^4的正整数,且宗教值不大于C。
显然和树剖有关。
然后我们发现宗教信仰有点恶心。
怎么办呢?对于每一种信仰建一棵线段树——>指针实现。
这样的话,我们相当于只需要维护信仰种类棵“动态开点线段树”。
然后相应维护一下几个操作就可以了。
code:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define ms(a,x) memset(a,x,sizeof a) 5 typedef long long LL; 6 7 void OJ() { 8 #ifndef ONLINE_JUDGE 9 freopen("in.txt","r",stdin); 10 freopen("out.txt","w",stdout); 11 #endif 12 } 13 14 namespace fastIO { 15 #define puc(c) putchar(c) 16 char ch; 17 inline int read() { 18 int x=0,f=1; ch=getchar(); 19 while (ch<‘0‘||ch>‘9‘) { 20 if (ch==‘-‘) f=-f; 21 ch=getchar(); 22 } 23 while (ch>=‘0‘&&ch<=‘9‘) { 24 x=(x<<3)+(x<<1)+ch-‘0‘; 25 ch=getchar(); 26 } 27 return x*f; 28 } 29 inline char readc() { 30 ch=getchar(); 31 while (ch<‘A‘||ch>‘Z‘) { 32 ch=getchar(); 33 } 34 return ch; 35 } 36 int cnt,num[20]; 37 template <class T> inline void write(T x) { 38 if (x==0) { 39 puc(‘0‘); return; 40 } 41 for (cnt=0; x; x/=10) num[++cnt]=x%10; 42 for (; cnt; --cnt) puc(num[cnt]+48); 43 } 44 inline void newline() { 45 puc(‘\n‘); 46 } 47 } using namespace fastIO; 48 49 const int N=100005; 50 int n,w[N],c[N],pos[N]; 51 #define sgt node 52 struct sgt { 53 node* l,* r; 54 int s,m; 55 node () { 56 l=r=0; 57 s=m=0; 58 } 59 inline void init (node* c) { 60 c=0; 61 } 62 #define max(a,b) ((a)>(b)?(a):(b)) 63 inline void update (node* c) { 64 c->s=0; 65 if (c->l) c->s+=c->l->s; 66 if (c->r) c->s+=c->r->s; 67 c->m=0; 68 if (c->l) c->m=max(c->m,c->l->m); 69 if (c->r) c->m=max(c->m,c->r->m); 70 } 71 #define M ((l)+(r)>>1) 72 inline void modify (node* &c,int l,int r,int x,int w) { 73 if (l>r) return; 74 if (!c) c=new node(); 75 if (l==r) { 76 c->m=w,c->s=w; 77 return; 78 } 79 if (x<=M) modify(c->l,l,M,x,w); 80 if (x>M) modify(c->r,M+1,r,x,w); 81 update(c); 82 } 83 inline int reply_s (node* &c,int l,int r,int x,int y,int ret=0) { 84 if (l>y||r<x||!c) return 0; 85 if (x<=l&&r<=y) return c->s; 86 if (y<=M) ret=reply_s(c->l,l,M,x,y); else 87 if (x>M) ret=reply_s(c->r,M+1,r,x,y); else 88 ret=reply_s(c->l,l,M,x,y)+reply_s(c->r,M+1,r,x,y); 89 return ret; 90 } 91 inline int reply_m (node* &c,int l,int r,int x,int y,int ret=0) { 92 if (l>y||r<x||!c) return 0; 93 if (x<=l&&r<=y) return c->m; 94 if (y<=M) ret=reply_m(c->l,l,M,x,y); else 95 if (x>M) ret=reply_m(c->r,M+1,r,x,y); else 96 ret=max(reply_m(c->l,l,M,x,y),reply_m(c->r,M+1,r,x,y)); 97 return ret; 98 } 99 } sg,*s[N]; 100 class TCP { 101 private: 102 int tot,lnk[N],nxt[N<<1],son[N<<1]; 103 int fa[N],dep[N],siz[N],got[N]; 104 int clo,dfn[N],top[N]; 105 public: 106 inline void init() { 107 tot=0,ms(lnk,0),ms(nxt,0); 108 fa[1]=0,dep[0]=0,siz[0]=0; 109 clo=0; 110 } 111 inline void add(int x,int y) { 112 nxt[++tot]=lnk[x],lnk[x]=tot,son[tot]=y; 113 } 114 inline void dfs(int x,int p) { 115 fa[x]=p,dep[x]=dep[p]+1,siz[x]=1,got[x]=0; 116 for (int j=lnk[x]; j; j=nxt[j]) { 117 if (son[j]==p) continue; 118 dfs(son[j],x); 119 siz[x]+=siz[son[j]]; 120 if (siz[son[j]]>siz[got[x]]) got[x]=son[j]; 121 } 122 } 123 inline void redfs(int x,int r) { 124 dfn[x]=++clo,pos[clo]=x,top[x]=r; 125 if (got[x]) redfs(got[x],r); 126 for (int j=lnk[x]; j; j=nxt[j]) { 127 if (son[j]==fa[x]||son[j]==got[x]) continue; 128 redfs(son[j],son[j]); 129 } 130 } 131 inline void modify (int c,int x,int w) { 132 sg.modify(s[c],1,n,dfn[x],w); 133 } 134 #define max(a,b) ((a)>(b)?(a):(b)) 135 inline int reply_s (int c,int x,int y,int ret=0) { 136 while (top[x]!=top[y]) { 137 if (dep[top[x]]<dep[top[y]]) std::swap(x,y); 138 ret+=sg.reply_s(s[c],1,n,dfn[top[x]],dfn[x]); 139 x=fa[top[x]]; 140 } 141 if (dep[x]<dep[y]) std::swap(x,y); 142 ret+=sg.reply_s(s[c],1,n,dfn[y],dfn[x]); 143 return ret; 144 } 145 inline int reply_m (int c,int x,int y,int ret=0) { 146 while (top[x]!=top[y]) { 147 if (dep[top[x]]<dep[top[y]]) std::swap(x,y); 148 ret=max(ret,sg.reply_m(s[c],1,n,dfn[top[x]],dfn[x])); 149 x=fa[top[x]]; 150 } 151 if (dep[x]<dep[y]) std::swap(x,y); 152 ret=max(ret,sg.reply_m(s[c],1,n,dfn[y],dfn[x])); 153 return ret; 154 } 155 } t; 156 int m; 157 int main() { 158 OJ(); char opt; int x,y; 159 n=read(),m=read(),t.init(); 160 for (int i=1; i<=100000; ++i) sg.init(s[i]); 161 for (int i=1; i<=n; ++i) w[i]=read(),c[i]=read(); 162 for (int i=1; i<n; ++i) { 163 x=read(),y=read(); 164 t.add(x,y),t.add(y,x); 165 } 166 t.dfs(1,0),t.redfs(1,1); 167 for (int i=1; i<=n; ++i) t.modify(c[i],i,w[i]); 168 for ( ; m; --m) { 169 opt=readc(); 170 if (opt==‘C‘) { 171 opt=readc(),x=read(),y=read(); 172 if (opt==‘C‘) { 173 t.modify(c[x],x,0); 174 t.modify(c[x]=y,x,w[x]); 175 } else { 176 t.modify(c[x],x,w[x]=y); 177 } 178 } else { 179 opt=readc(),x=read(),y=read(); 180 if (opt==‘S‘) { 181 write(t.reply_s(c[x],x,y)); 182 newline(); 183 } else { 184 write(t.reply_m(c[x],x,y)); 185 newline(); 186 } 187 } 188 } 189 return 0; 190 }