[SDOI2011] 染色(树链剖分)

题目描述

输入输出格式

输入格式:

输出格式:

对于每个询问操作,输出一行答案。

输入输出样例

输入样例#1:

6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5

输出样例#1:

3
1
2

说明


Solution

太久没打过树剖了哈,代码能力弱的一批...

这道题需要进行改进的地方是线段树部分.
我们新维护两个变量:
\[ll[node],rr[node]\]
分别用于储存当前线段树节点的左端颜色和右端颜色.
以在查询时达到判重的作用.

修改时也只需要注意下这两个变量即可.

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=100008;
struct sj{int to,next;}a[maxn*2];
int x,y,z,dep[maxn],fa[maxn];
int n,m,col[maxn],c[maxn],num;
int head[maxn],size,id[maxn],fuck[maxn];
int siz[maxn],zu[maxn],son[maxn];
int ll[maxn*4],rr[maxn*4],sgm[maxn*4],lazy[maxn*4];
void add(int x,int y)
{
    a[++size].to=y;
    a[size].next=head[x];
    head[x]=size;
}

void dfs1(int x)
{
    siz[x]=1;
    for(int i=head[x];i;i=a[i].next)
    {
        int tt=a[i].to;
        if(!siz[tt])
        {
            dep[tt]=dep[x]+1;
            fa[tt]=x;
            dfs1(tt);
            siz[x]+=siz[tt];
            if(siz[tt]>siz[son[x]])
            son[x]=tt;
        }
    }
}

void dfs2(int x,int anc)
{   
    zu[x]=anc; c[++num]=col[x]; id[x]=num;
    if(son[x]) dfs2(son[x],anc);
    for(int i=head[x];i;i=a[i].next)
    {
        int tt=a[i].to;
        if(!zu[tt])
            if(tt==son[x])
                continue;
            else dfs2(tt,tt);
    }
}

void push_down(int node)
{
    ll[node*2]=lazy[node]; rr[node*2]=lazy[node];
    ll[node*2+1]=lazy[node]; rr[node*2+1]=lazy[node];    
    sgm[node*2]=1; sgm[node*2+1]=1;                                            
    lazy[node*2]=lazy[node]; lazy[node*2+1]=lazy[node];
    lazy[node]=0;
}

void update(int node)
{
    ll[node]=ll[node*2]; rr[node]=rr[node*2+1];  
    sgm[node]=sgm[node*2]+sgm[node*2+1];
    if(rr[node*2]==ll[node*2+1]) sgm[node]--;
}

void build(int node,int l,int r)
{
    if(l==r)
    {
        ll[node]=c[l];
        rr[node]=c[r];
        sgm[node]=1;
        return;
    }

    int mid=(l+r)/2;
    build(node*2,l,mid);
    build(node*2+1,mid+1,r);
    update(node);
    return;
}

void change(int node,int l,int r,int L,int R,int cc)
{
    if(l>R||L>r)return;
    if(l>=L&&r<=R)
    {
        lazy[node]=cc;      
        ll[node]=lazy[node];
        rr[node]=lazy[node];
        sgm[node]=1;
        return; 
    }

    if(lazy[node]!=0)
    push_down(node);
    int mid=(l+r)/2;
    change(node*2,l,mid,L,R,cc);
    change(node*2+1,mid+1,r,L,R,cc);
    update(node);
}

int query(int node,int l,int r,int L,int R)
{
    if(l>R||L>r)return 0;
    if(l>=L&&r<=R){
        return sgm[node];}
    if(lazy[node]!=0)
    push_down(node);
    int mid=(l+r)/2;
    int lll=query(node*2,l,mid,L,R);
    int rrr=query(node*2+1,mid+1,r,L,R);
    int ans=lll+rrr;
    if(rr[node*2]==ll[node*2+1]&&(lll!=0&&rrr!=0))return ans-1;
    return ans;
}

void kuai(int x,int y,int z)
{
    while(zu[x]!=zu[y])
    {
        if(dep[zu[x]]<dep[zu[y]])
        swap(x,y);
        change(1,1,n,id[zu[x]],id[x],z);
        x=fa[zu[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    change(1,1,n,id[x],id[y],z);
}

int newww(int r,int z,int y,int p)
{
    if (z==y) return ll[r];
    if (lazy[r]) push_down(r);
    int k=(z+y)/2;
    if (p>k) return newww(r*2+1,k+1,y,p);
    else return newww(r*2,z,k,p);
}

int check(int x,int y)
{
    int kk=0,nx,ny;
    while (zu[x]!=zu[y]) 
    {
        if (dep[zu[x]]>dep[zu[y]]) 
        swap(x,y);
        kk+=query(1,1,n,id[zu[y]],id[y]);
        nx=newww(1,1,n,id[zu[y]]);
        ny=newww(1,1,n,id[fa[zu[y]]]);
        y=fa[zu[y]];
        if (nx==ny) kk--;
    }
    if (dep[x]>dep[y]) swap(x,y);
    kk+=query(1,1,n,id[x],id[y]);
    cout<<(kk?kk:1)<<endl;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    scanf("%d",&col[i]);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    dfs1(1);
    dfs2(1,1);
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        char ch; cin>>ch;
        if(ch=='Q')
            scanf("%d%d",&x,&y),
            check(x,y);
        else
            scanf("%d%d%d",&x,&y,&z),
            kuai(x,y,z);
    }
}

猜你喜欢

转载自www.cnblogs.com/Kv-Stalin/p/9237246.html