码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2243 sdoi2011 染色 paint

时间:2015-05-05 01:14:07      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+fastio来gangbang

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cctype>
using namespace std;

const int Maxn=100010,Maxm=Maxn;

int n,m;

const int D=1000000;
char in[D],out[D/10],*I=in,*O=out;

inline char gc(){
    return *(I++);
}

inline void pc(const char& c){
    *(O++)=c;
}

template <typename Q>
inline void pt(Q x){
    if(x==0) pc(0);
    if(x<0) pc(-),x=-x;
    static int stk[20],top;
    top=0;
    for(;x;x/=10) stk[++top] = x%10;
    for(int i=top;i;--i) pc(stk[i]+0);
}

template <typename Q>
inline void gt(Q& x){
    static char c,f;
    for(c=gc(),f=0;!isdigit(c);c=gc()) if(c==-) f=1;
    for(x=0;isdigit(c);c=gc()) x=x*10+c-0;
    if(f) x=-x;
}

struct Data {
    int l,r,num;
    Data (int l=-1,int r=-1,int num=0):l(l),r(r),num(num) {}
    Data operator + (const Data& rhs)const {
        if(rhs.l==-1 && l==-1 ) exit(-1);
        if(rhs.l==-1) return *this;
        if(l==-1) return rhs;
        return Data(l,rhs.r,num+rhs.num-(r==rhs.l));
        Data ret(l,rhs.r,num+rhs.num);
        if(r==rhs.l) ret.num--;
        return ret;
    }
    Data operator ~()const {
        return Data(r,l,num);
    }
};

int tbld[Maxn];

struct SegmentTree {
    Data da[Maxn*4];
    int tag[Maxn*4];
    int lft,rgt,w;

    SegmentTree() {
        memset(tag,-1,sizeof tag);
    }
    
    void build(int o,int l,int r){
        if(l==r) {
            da[o] = Data(tbld[l],tbld[l],1);
            return;
        }
        int mid=(l+r)>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
        da[o] = da[o<<1] + da[o<<1|1];
    }

    void add(int o,int col) {
        da[o]=Data(col,col,1);
        tag[o]=col;
    }

    void down(int o) {
        if(tag[o]==-1) return;
        add(o<<1,tag[o]);
        add(o<<1|1,tag[o]);
        tag[o]=-1;
    }

    void pp(int l,int r=0,int w=0) {
        lft=l,rgt=r;
        this->w=w;
    }

    void change(int o,int l,int r) {
        if(lft<=l && r<=rgt) {
            add(o,w);
            return;
        }
        down(o);
        int mid=(l+r)>>1;
        if(lft<=mid) change(o<<1,l,mid);
        if(mid<rgt) change(o<<1|1,mid+1,r);
        da[o]=da[o<<1]+da[o<<1|1];
    }

    Data query(int o,int l,int r) {    
        if(lft<=l && r<=rgt) {
            return da[o];
        }
        down(o);
        int mid=(l+r)>>1;
        if(rgt<=mid) return query(o<<1,l,mid);
        if(mid<lft) return query(o<<1|1,mid+1,r);
        return query(o<<1,l,mid)+query(o<<1|1,mid+1,r);
    }
    
    Data query(int l,int r){
        pp(l,r);
        return query(1,1,n);
    }
    
    void change2(int l,int r,int w){
        pp(l,r,w);
        change(1,1,n);
    }
} seg;

int fir[Maxn],next[Maxm*2],en[Maxm*2];
int tot=0;
void Add(int from,int to) {
    en[++tot] = to;
    next[tot] = fir[from];
    fir[from] = tot;
}

int sz[Maxn],son[Maxn],fa[Maxn],dep[Maxn];

void dfs(int u) {
    sz[u] = 1;
    son[u] = 0;
    for(int k=fir[u]; k; k=next[k]) {
        const int&v=en[k];
        if(v == fa[u]) continue;
        fa[v] = u;
        dep[v] = dep[u]+1;
        dfs(v);
        sz[u] += sz[v];
        if(sz[v]>sz[son[u]]) son[u] = v;
    }
}

int top[Maxn],pos[Maxn],color[Maxn],clk=0;

void build(int u,int pre) {
    top[u] = pre;
    pos[u] = ++clk;
    tbld[clk] = color[u];
    if(son[u]) build(son[u],pre);
    for(int k=fir[u]; k; k=next[k]) {
        const int&v = en[k];
        if(v==fa[u] || v==son[u]) continue;
        build(v,v);
    }
}

void change(int a,int b,int c){
    int ta=top[a],tb=top[b];
    for(;ta!=tb;a=fa[ta],ta=top[a]){
        if(dep[ta] < dep[tb] ) swap(a,b), swap(ta,tb);
        seg.change2(pos[ta],pos[a],c);
    }
    if(dep[a]>dep[b]) swap(a,b);
    seg.change2(pos[a],pos[b],c);
}

Data query(int a,int b) {
    int ta=top[a],tb=top[b];
    
    Data res1,res2;
    
    for(;ta!=tb;){
        if(dep[ta]>dep[tb]){
            res1 = seg.query(pos[ta],pos[a]) + res1;//注意这里以及下面加的顺序,写的时候没想好,调了好久 
            a=fa[ta],ta=top[a];
        } else {
            res2 = seg.query(pos[tb],pos[b]) + res2;
            b=fa[tb],tb=top[b];
        }
    }
//    Data tmp ( seg.query(pos[b],pos[a]) );
    if(dep[a]<dep[b]) return (~res1)+seg.query(pos[a],pos[b])+res2;//还有这里要取反各种坑,各种要注意顺序 
//     tmp=(~res2)+seg.query(pos[b],pos[a]);
//    tmp=tmp+res1;
    return (~res2)+seg.query(pos[b],pos[a])+res1;
}

int main() {
    freopen("paint.in","r",stdin);
    freopen("paint.out","w",stdout);

    fread(in,1,D,stdin);

    gt(n),gt(m);
    
    for(int i=1;i<=n;i++) gt(color[i]);
    
    for(int u,v,i=1;i<n;i++){
        gt(u),gt(v);
        Add(u,v);
        Add(v,u);
    }
    
    dfs(1);
    build(1,1);
    seg.build(1,1,n);
    
//    for(int i=1;i<=n;i++) printf("%d\n",son[i]);
//    return 0;
    
    char cmd;
    int a,b,c;
    
//    for(I=1;I<=m;I++)
    for(;m--;){
        
        /*if(I==2) {
            Data tmp=seg.query( pos[2],pos[7] );
            tmp=seg.query( pos[3],pos[4]);
            tmp=seg.query( pos[2],pos[6]);
            tmp=seg.query( pos[6],pos[7]);
            I=2;
        }*/
        
        for(cmd=gc();cmd!=Q&&cmd!=C;cmd=gc());
        gt(a);gt(b);
        if(cmd == Q) pt(query(a,b).num),pc(\n);
        else gt(c), change(a,b,c);
    }
    
    return printf(out),0;
}

 

bzoj2243 sdoi2011 染色 paint

标签:

原文地址:http://www.cnblogs.com/showson/p/4478042.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!