【BZOJ4999】This Problem Is Too Simple!(线段树)
2018-03-13 15:32
543 查看
【BZOJ4999】This Problem Is Too Simple!(线段树)
题面
BZOJ题解
对于每个值,维护一棵线段树就好啦动态开点,否则空间开不下
剩下的就是很简单的问题啦
当然了,对于数值要离散化
没必要离线吧,在线用\(map\)维护就行了
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define ll long long #define RG register #define MAX 120000 #define lson (t[x].ls) #define rson (t[x].rs) inline int read() { RG int x=0,t=1;RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } struct Line{int v,next;}e[MAX<<1]; int h[MAX],cnt=1; inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;} map<int,int> M; int tim,dfn[MAX],hson[MAX],size[MAX],fa[MAX],top[MAX],C[MAX],dep[MAX]; void dfs1(int u,int ff) { fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1; for(int i=h[u];i;i=e[i].next) { int v=e[i].v; if(v==ff)continue; dfs1(v,u); if(size[v]>size[hson[u]])hson[u]=v; size[u]+=size[v]; } } void dfs2(int u,int tp) { top[u]=tp;dfn[u]=++tim; if(hson[u])dfs2(hson[u],tp); for(int i=h[u];i;i=e[i].next) if(e[i].v!=fa[u]&&e[i].v!=hson[u]) dfs2(e[i].v,e[i].v); } struct Node{int ls,rs,v;}t[MAX<<7]; int tot,sum,rt[MAX<<2]; int n,Q; void Modify(int &x,int l,int r,int p,int w) { if(!x)x=++tot;t[x].v+=w; if(l==r)return; int mid=(l+r)>>1; if(p<=mid)Modify(lson,l,mid,p,w); else Modify(rson,mid+1,r,p,w); } int Query(int x,int l,int r,int L,int R) { if((!t[x].v)||(!x))return 0; if(L<=l&&r<=R)return t[x].v; int mid=(l+r)>>1,ret=0; if(L<=mid)ret+=Query(lson,l,mid,L,R); if(R>mid)ret+=Query(rson,mid+1,r,L,R); return ret; } int Route(int u,int v,int x) { int ret=0; while(top[u]!=top[v]) { if(dep[top[u]]<dep[top[v]])swap(u,v); ret+=Query(rt[x],1,n,dfn[top[u]],dfn[u]); u=fa[top[u]]; } if(dep[u]<dep[v])swap(u,v); ret+=Query(rt[x],1,n,dfn[v],dfn[u]); return ret; } int main() { n=read();Q=read(); for(int i=1;i<=n;++i)C[i]=read(); for(int i=1;i<n;++i) { int u=read(),v=read(); Add(u,v);Add(v,u); } dfs1(1,0);dfs2(1,1); for(int i=1;i<=n;++i) { if(!M[C[i]])M[C[i]]=++sum; Modify(rt[M[C[i]]],1,n,dfn[i],1); } char ch[5]; while(Q--) { scanf("%s",ch); if(ch[0]=='C') { int u=read(),x=read(); Modify(rt[M[C[u]]],1,n,dfn[u],-1); if(!M[x])M[x]=++sum; Modify(rt[M[x]],1,n,dfn[u],1); C[u]=x; } else { int u=read(),v=read(),x=read(); if(!M[x])puts("0"); else printf("%d\n",Route(u,v,M[x])); } } return 0; }
相关文章推荐
- bzoj4999 This Problem Is Too Simple!(树链剖分+动态开点线段树)
- 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树
- 【BZOJ4999】This Problem Is Too Simple!(线段树)
- bzoj 4999 This problem is too simple 树链剖分+动态开点线段树
- BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树
- BZOJ4999: This Problem Is Too Simple!
- 【bzoj4999】This Problem Is Too Simple!
- BZOJ[4999]This Problem Is Too Simple! 树链剖分
- bzoj 4999: This Problem Is Too Simple! 树链剖分+线段树
- bzoj4999: This Problem Is Too Simple!
- bzoj 4999: This Problem Is Too Simple!
- [BZOJ]4999: This Problem Is Too Simple! 树链剖分
- 【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA
- bzoj 4999: This Problem Is Too Simple!
- BZOJ 4999: This Problem Is Too Simple!
- bzoj 4999: This Problem Is Too Simple!
- 4999: This Problem Is Too Simple!
- 4999: This Problem Is Too Simple!
- bzoj4999 This Problem Is Too Simple!
- bzoj 3212: Pku3468 A Simple Problem with Integers (线段树)