# bzoj 4999: This Problem Is Too Simple！

## Description

1. C i x(0<=x<2^31) 表示将i节点的值改为x。
2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。

5 6
10 20 30 40 50
1 2
1 3
3 4
3 5
Q 2 3 40
C 1 40
Q 2 3 40
Q 4 5 30
C 3 10
Q 4 5 30

## Sample Output

0
1
1
0
————————————————————————————

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
const int M=1e6+7,mod=9875321;
int ans=0,f=1,c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
return ans*f;
}
int n,m,k,v[M],l[M],r[M],pos[M];
int first[M],cnt,ans[M],mark[M];
struct node{int to,next;}e[2*M];
void ins(int a,int b){e[++cnt]=(node){b,first[a]}; first[a]=cnt;}
void insert(int a,int b){ins(a,b); ins(b,a);}
int dep[M],f[M][25],sum;
void dfs(int x){
l[x]=pos[x]=++sum;
for(int i=1;(1<<i)<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
for(int i=first[x];i;i=e[i].next){
int now=e[i].to;
if(!dep[now]){
dep[now]=dep[x]+1;
f[now][0]=x;
dfs(now);
}
}r[x]=sum;
}
int find(int x,int y){
if(dep[x]<dep[y]) std::swap(x,y);
int d=dep[x]-dep[y];
for(int i=0;(1<<i)<=d;i++) if(1<<i&d) x=f[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
struct P{int s,x,T;};
std::vector<P>e1[M];
struct Q{int l,r,T;};
std::vector<Q>e2[M];
int star[mod],cnth;
struct H{int to,next;}hash[M];
int get(int x){
int w=x%mod;
for(int i=star[w];i;i=hash[i].next) if(hash[i].to==x) return i;
cnth++; hash[cnth].to=x; hash[cnth].next=star[w]; star[w]=cnth;
return cnth;
}
char c[5];
int s[M],now[M];
int lowbit(int x){return x&-x;}
while(x<=n){
if(now[x]!=k) now[x]=k,s[x]=0;
s[x]+=ss;
x+=lowbit(x);
}
}
int query(int x){
int ans=0;
while(x){
if(now[x]==k) ans+=s[x];
x-=lowbit(x);
}
return ans;
}
int main(){
for(int i=1;i<=n;i++){
e1[v[i]].push_back((P){1,i,0});
}
int x,y;
dep[1]=1; dfs(1);
for(int i=1;i<=m;i++){
scanf("%s",c);
if(c[0]=='C'){
if(v[x]==k) continue;
e1[k].push_back((P){1,x,i});
e1[v[x]].push_back((P){-1,x,i});
v[x]=k;
}
else{
mark[i]=1;
e2[k].push_back((Q){x,y,i});
}
}
for(k=1;k<=cnth;k++){
int now=0;
P* h1=e1[k].data();
Q* h2=e2[k].data();
for(int i=0;i<e2[k].size();i++){
while(now<e1[k].size()&&h1[now].T<=h2[i].T){
now++;
}
int id=h2[i].T;
ans[id]+=query(pos[h2[i].l]); ans[id]+=query(pos[h2[i].r]);
int lca=find(h2[i].l,h2[i].r),fa=f[lca][0];
ans[id]-=query(pos[lca]); ans[id]-=query(pos[fa]);
}
}
for(int i=1;i<=m;i++)if(mark[i]) printf("%d\n",ans[i]);
return 0;
}
View Code

posted @ 2017-08-30 16:38  友人Aqwq  阅读(...)  评论(...编辑  收藏