首页 > 代码库 > HYSBZ 2243(染色)

HYSBZ 2243(染色)

题目链接:传送门

题目大意:中文题,略

题目思路:树链剖分,区间更新,区间查询。

闲谈:      只想说这道题做的好苦逼。。去长春现场赛之前就没A,回来后又做了2天才A掉,蒟蒻太菜了

     这道题也没有想象中那么难,就是代码有点长。。

     在查询的时候注意判断端点交界处如果相同则答案-1。

 

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <cctype>#include <queue>#include <string>#include <vector>#include <set>#include <map>#include <climits>#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define fi first#define se second#define ping(x,y) ((x-y)*(x-y))#define mst(x,y) memset(x,y,sizeof(x))#define mcp(x,y) memcpy(x,y,sizeof(y))using namespace std;#define gamma 0.5772156649015328606065120#define MOD 1000000007#define inf 0x3f3f3f3f#define N 100005#define maxn 30010typedef pair<int,int> PII;typedef long long LL;LL read(){    LL x=0,f=1;char ch=getchar();    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}    while(ch>=0&&ch<=9){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}    return x*f;}int n,m,k,sz,L,R;int a[N],mrk[N<<2];struct Seg{int l,r,v;}seg[N<<2];int son[N],siz[N],id[N],tid,posi[N];int top[N],fa[N],dep[N],head[N],hcnt;struct Node{int to,nxt;}node[N<<1];void dfs1(int u,int f,int deep){    dep[u]=deep,fa[u]=f,siz[u]=1;    for(int i=head[u];~i;i=node[i].nxt){        int e=node[i].to;        if(e==f)continue;        dfs1(e,u,deep+1);        siz[u]+=siz[e];        if(!son[u]||siz[son[u]]<siz[e])            son[u]=e;    }}void dfs2(int u,int tp){    top[u]=tp,id[u]=++tid,posi[tid]=u;    if(!son[u])return;dfs2(son[u],tp);    for(int i=head[u];~i;i=node[i].nxt){        int e=node[i].to;        if(!id[e])dfs2(e,e);    }}void pushdown(int rt){    seg[rt<<1].v=seg[rt<<1|1].v=1;    seg[rt<<1].l=seg[rt<<1].r=mrk[rt];    seg[rt<<1|1].l=seg[rt<<1|1].r=mrk[rt];    mrk[rt<<1]=mrk[rt<<1|1]=mrk[rt];mrk[rt]=-1;}int query(int rt,int l,int r){    if(L<=l&&r<=R)return seg[rt].v;    int mid=l+r>>1,temp=0,t1=-1,t2=-1;    if(~mrk[rt])pushdown(rt);    if(L<=mid)t1=seg[rt<<1].r,temp+=query(lson);    if(R>mid) t2=seg[rt<<1|1].l,temp+=query(rson);    seg[rt].l=seg[rt<<1].l,seg[rt].r=seg[rt<<1|1].r;    seg[rt].v=seg[rt<<1].v+seg[rt<<1|1].v-(seg[rt<<1].r==seg[rt<<1|1].l);    temp-=(t1==t2&&t1!=-1);    return temp;}void update(int rt,int l,int r,int v){    if(L<=l&&r<=R){seg[rt].v=1,seg[rt].l=seg[rt].r=mrk[rt]=v;return;}    int mid=l+r>>1;    if(~mrk[rt])pushdown(rt);    if(L<=mid)update(lson,v);    if(R>mid) update(rson,v);    seg[rt].l=seg[rt<<1].l,seg[rt].r=seg[rt<<1|1].r;    seg[rt].v=seg[rt<<1].v+seg[rt<<1|1].v-(seg[rt<<1].r==seg[rt<<1|1].l);}int findp(int rt,int l,int r,int L){    if(l==r)return seg[rt].l;    int mid=l+r>>1,temp;    if(~mrk[rt])pushdown(rt);    if(L<=mid)return findp(lson,L);    else return findp(rson,L);}void lca(int x,int y){    int res=0;    while(top[x]!=top[y]){        if(dep[top[x]]<dep[top[y]])swap(x,y);        L=id[top[x]],R=id[x];        res+=query(1,1,n);        L=id[x];        if(findp(1,1,n,id[top[x]])==findp(1,1,n,id[fa[top[x]]]))--res; ///看两端是否相同        x=fa[top[x]];    }    if(dep[x]>dep[y])swap(x,y);    L=id[x],R=id[y];    res+=query(1,1,n);    printf("%d\n",res);}void change(int x,int y,int v){    while(top[x]!=top[y]){        if(dep[top[x]]<dep[top[y]])swap(x,y);        L=id[top[x]],R=id[x];        update(1,1,n,v);        x=fa[top[x]];    }    if(dep[x]>dep[y])swap(x,y);    L=id[x],R=id[y];    update(1,1,n,v);}void build(int rt,int l,int r){    if(l==r){seg[rt].l=seg[rt].r=a[posi[l]],seg[rt].v=1;return;}    int mid=l+r>>1;    build(lson);build(rson);    seg[rt].v=seg[rt<<1].v+seg[rt<<1|1].v-(seg[rt<<1].r==seg[rt<<1|1].l);    seg[rt].l=seg[rt<<1].l,seg[rt].r=seg[rt<<1|1].r;}int main(){    int i,j,group,x,y,v;    n=read(),m=read();mst(head,-1);mst(mrk,-1);    for(i=1;i<=n;++i)a[i]=read();    for(i=1;i<n;++i){        x=read(),y=read();        node[hcnt].to=y;node[hcnt].nxt=head[x],head[x]=hcnt++;        node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;    }    dfs1(1,1,1);dfs2(1,1);build(1,1,n);    char ch;    while(m--){        scanf(" %c",&ch);        x=read(),y=read();        if(ch==Q) lca(x,y);        else v=read(),change(x,y,v);    }    return 0;}

 

HYSBZ 2243(染色)