题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3531
题意概述:
给出一棵N个点的树,树上的每个结点有一个颜色和权值,支持以下四种操作:
1.将点x的颜色改成c。
2.将点x的权值给成w。
3.询问x->y路径上和端点相同颜色的点的权值总和(端点颜色相同)。
4.询问x->y路径上和端点相同颜色的点的权值最大值(端点颜色相同)。
分析:
首先树链剖分,每条链开C棵维护每个颜色的线段树。动态开点。
感觉没什么好说的......考试的时候灵光一闪就来了......之前还在YYlct之类的......
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<set> 9 #include<map> 10 #include<vector> 11 #include<cctype> 12 using namespace std; 13 const int maxn=100005; 14 const int SIZE=4000005; 15 16 int N,Q,C[maxn],W[maxn]; 17 map<int,int>rt[maxn]; 18 struct edge{ int to,next; }E[maxn<<1]; 19 int first[maxn],np,dep[maxn],top[maxn],fa[maxn],son[maxn],sz[maxn],len[maxn]; 20 int lc[SIZE],rc[SIZE],sum[SIZE],mx[SIZE],np2; 21 22 void _scanf(int &x) 23 { 24 x=0; 25 char ch=getchar(); 26 while(ch<'0'||ch>'9') ch=getchar(); 27 while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); 28 } 29 void _scanf(char *s) 30 { 31 int cnt=0; 32 char ch=getchar(); 33 while(!isalpha(ch)) ch=getchar(); 34 while(isalpha(ch)) s[cnt++]=ch,ch=getchar(); 35 s[cnt]='