题目(bzoj)
题目(洛谷)
这题其实也没什么好说的......
主要是考虑区间合并时每个区间两端的颜色是否相同,相同的话ans--
完毕。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <climits> #define ll long long #define llmax LONG_LONG_MAX #define llmin LONG_LONG_MIN #define ls id<<1 #define rs id<<1|1 #define inf INT_MAX #define readf(f) scanf( #define N 100005 using namespace std; template <class _E> inline void read(_E &e) { e=0;bool ck=0;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')ck=1;ch=getchar();} while(ch>='0'&&ch<='9'){e=e*10+ch-'0';ch=getchar();} if(ck)e=-e; } int n,M; struct edge{int vk;int nxt;}e[N*2]; struct Segment_tree{int l;int r;int cnt;int lc;int rc;int lazy;}t[N<<2]; int tt,head[N]; inline void ad(int u,int v){e[++tt].vk=v;e[tt].nxt=head[u];head[u]=tt;} int c[N]; int dep[N],siz[N],rank[N],son[N],f[N],top[N],pre[N],idx; void dfs1(int u,int fa) { siz[u]=1;f[u]=fa; for (int i=head[u];i;i=e[i].nxt) { int v=e[i].vk; if (v==fa) continue; dep[v]=dep[u]+1; dfs1(v,u); siz[u]+=siz[v]; if (!son[u] || siz[v]>siz[son[u]]) son[u]=v; } } void dfs2(int u,int fa) { top[u]=fa; rank[u]=++idx;pre[rank[u]]=u; if (!son[u]) return; dfs2(son[u],fa); for (int i=head[u];i;i=e[i].nxt) { int v=e[i].vk; if (v==f[u] || v==son[u]) continue; dfs2(v,v); } } inline void up(int id) { t[id].lc=t[ls].lc,t[id].rc=t[rs].rc; t[id].cnt=t[ls].cnt+t[rs].cnt; if (t[ls].rc==t[rs].lc) --t[id].cnt; } inline void down(int id) { if (t[id].lazy) { t[ls].lazy=t[rs].lazy=t[id].lazy; t[ls].cnt=t[rs].cnt=1; t[ls].lc=t[ls].rc=t[id].lc; t[rs].lc=t[rs].rc=t[id].lc; t[id].lazy=0; } } void build(int l,int r,int id) { t[id].l=l,t[id].r=r;t[id].cnt=0; if (l==r) return; int mid=(l+r)>>1; build(l,mid,ls),build(mid+1,r,rs); } void update(int col,int l,int r,int id) { int L=t[id].l,R=t[id].r; if (L==l && R==r) { t[id].cnt=t[id].lazy=1; t[id].lc=t[id].rc=col; return; } down(id); int mid=(L+R)>>1; if (r<=mid) update(col,l,r,ls); else if (l>mid) update(col,l,r,rs); else update(col,l,mid,ls),update(col,mid+1,r,rs); up(id); } int lcol,rcol; int query(int l,int r,int id,int L,int R) { int L1=t[id].l,R1=t[id].r; if (L1==L) lcol=t[id].lc; if (R1==R) rcol=t[id].rc; if (L1==l && R1==r) return t[id].cnt; down(id); int mid=(L1+R1)>>1; if (r<=mid) return query(l,r,ls,L,R); else if (l>mid) return query(l,r,rs,L,R); else { int ret=query(l,mid,ls,L,R)+query(mid+1,r,rs,L,R); if (t[ls].rc==t[rs].lc) --ret; return ret; } } inline void change(int x,int y,int col) { int f1=top[x],f2=top[y]; while (f1!=f2) { if (dep[f1]<dep[f2]) swap(x,y),swap(f1,f2); update(col,rank[f1],rank[x],1); x=f[f1];f1=top[x]; } if (dep[x]>dep[y]) swap(x,y); update(col,rank[x],rank[y],1); } inline int qans(int x,int y) { int a1=-1,a2=-1,ret=0; int f1=top[x],f2=top[y]; while (f1!=f2) { if (dep[f1]<dep[f2]) swap(x,y),swap(f1,f2),swap(a1,a2); ret+=query(rank[f1],rank[x],1,rank[f1],rank[x]); if (rcol==a1) --ret; a1=lcol; x=f[f1];f1=top[x]; } if (dep[x]<dep[y]) swap(x,y),swap(a1,a2); ret+=query(rank[y],rank[x],1,rank[y],rank[x]); if (a1==rcol) --ret; if (a2==lcol) --ret; return ret; } int main() { read(n);read(M); for (int i=1;i<=n;++i) read(c[i]); for (int i=1;i<n;++i) { int x,y; read(x),read(y); ad(x,y),ad(y,x); } dfs1(1,0);dfs2(1,1); build(1,n,1); for (int i=1;i<=n;++i) update(c[i],rank[i],rank[i],1); while (M--) { char ch[1]; int aa,bb,cc; scanf( if (ch[0]=='C') { read(aa),read(bb),read(cc); change(aa,bb,cc); } else { read(aa),read(bb); printf( } } return 0; }
Comments NOTHING