bzoj2243 sdoi2011 染色 paint

明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+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;
}

 

嗯,其实lct还是挺好写的,就是有点慢TAT

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<cstdio>
  6 using namespace std;
  7 
  8 const int Maxn = 100010;
  9 
 10 int ch[Maxn][2],p[Maxn],sz[Maxn],flip[Maxn],tag[Maxn];
 11 int col[Maxn];
 12 int n,m;
 13 
 14 const int D=15000000;
 15 char in[D],out[300010*10],*I=in,*O=out;
 16 #define gc (*I++)
 17 #define pc(x) ((*O++)=x)
 18 template <typename Q> 
 19 void gt(Q&x) {
 20     static char c,f;
 21     for(c=gc,f=0;!isdigit(c);c=gc)if(c=='-') f=1;
 22     for(x=0;isdigit(c);c=gc) x=x*10+c-'0';
 23     f && (x=-x);
 24 }
 25 
 26 struct Data {
 27     int l,r,num;
 28     Data(int l=-1,int r=-1,int num=0):l(l),r(r),num(num) {}
 29     Data operator + (const Data& rhs) const {
 30         if(!num) return rhs;
 31         if(!rhs.num) return *this;
 32         return Data (l,rhs.r,num+rhs.num-(r==rhs.l));
 33     }
 34     void flip() {
 35         swap(l,r);
 36     }
 37 }da[Maxn];
 38 
 39 template <typename Q>
 40 void pt(Q x){
 41     static char stk[20];
 42     static int top;
 43     top=0;
 44     if(x==0) pc('0');
 45     for(;x;x/=10) stk[++top] = x%10+'0';
 46     for(;top;top--) pc(stk[top]);
 47 }
 48 
 49 int fir[Maxn],next[Maxn*2],en[Maxn*2];
 50 void Add(int from,int to) {
 51     static int tot=0;
 52     en[++tot]=to;
 53     next[tot]=fir[from];
 54     fir[from]=tot;
 55 }
 56 
 57 void add_tag(int x,int Col) {
 58     if(x==0) return;
 59     col[x] = tag[x] = Col;
 60     da[x] = Data(Col,Col,1);
 61 }
 62 
 63 void down(int x) {
 64     if(flip[x]) {
 65         swap(ch[x][0],ch[x][1]);
 66         flip[ch[x][0]]^=1; da[ch[x][0]].flip();
 67         flip[ch[x][1]]^=1; da[ch[x][1]].flip();
 68         flip[x]=0;
 69     }
 70     if(tag[x]!=-1) {
 71         add_tag(ch[x][0],tag[x]);
 72         add_tag(ch[x][1],tag[x]);
 73         tag[x]=-1;
 74     }
 75 }
 76 
 77 bool isroot(int x){
 78     return ch[p[x]][0]!=x && ch[p[x]][1]!=x;
 79 }
 80 
 81 void update(int x) {
 82     if(x==0) return;
 83     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
 84     da[x]=da[ch[x][0]]+Data(col[x],col[x],1)+da[ch[x][1]];
 85 }
 86 
 87 void rotate(int x) {
 88     int y=p[x],z=p[y];
 89     int l=ch[y][1]==x,r=l^1;
 90     if(!isroot(y)) ch[z][ch[z][1]==y]=x;
 91     p[ch[x][r]]=y;
 92     p[y]=x;
 93     p[x]=z;
 94     
 95     ch[y][l]=ch[x][r];
 96     ch[x][r]=y;
 97     
 98     update(y);
 99     update(x);
100 }
101 
102 void splay(int x){
103     static int stk[Maxn],top;
104     stk[top=1]=x;
105     for(int t=x;!isroot(t);t=p[t]) stk[++top] = p[t];
106     for(;top;top--) down(stk[top]);
107     for(;!isroot(x);){
108         int y=p[x],z=p[y];
109         if(!isroot(y)){
110             if( (ch[y][1]==x)^(ch[z][1]==y) )
111                 rotate(x);else rotate(y);
112         }
113         rotate(x);
114     }
115 }
116 
117 void access(int x){
118     for(int t=0;x;x=p[t=x]){
119         splay(x);
120         ch[x][1]=t;
121         update(x);
122     }
123 }
124 
125 int getroot(int x){
126     for(access(x),splay(x);ch[x][0];x=ch[x][0]);
127     return x;
128 }
129 
130 void cut(int x){
131     access(x);
132     splay(x);
133     p[ch[x][0]]=0;
134     ch[x][0]=0;
135     update(x);    
136 }
137 
138 void combine(int x,int y) {
139     cut(x);
140     p[x]=y;
141     update(y);
142 }
143 
144 void newroot(int x){
145     access(x);
146     splay(x);
147     flip[x]^=1;
148     da[x].flip();
149 }
150 
151 void dfs(int x) {
152     for(int k=fir[x];k;k=next[k]) {
153         int v=en[k];
154         if(v==p[x]) continue;
155         p[v]=x;
156         dfs(v);
157     }
158 }
159 
160 void init(){
161     gt(n);gt(m);
162     memset(tag,-1,sizeof(*tag)*(n+1));
163     for(int i=1;i<=n;i++) {
164         gt(col[i]);
165         sz[i]=1;
166         da[i] = Data( col[i],col[i],1);
167     }
168     for(int u,v,i=1;i<n;i++) {
169         gt(u),gt(v);
170         Add(u,v);
171         Add(v,u);
172     }
173     dfs(1);
174 }
175 
176 void work() {
177     char cmd;
178     int a,b,c;
179     for(int i=1;i<=m;i++) {
180         for(cmd=gc;cmd!='C' && cmd!='Q';cmd=gc);
181         gt(a);gt(b);
182         newroot(a);
183         access(b);
184         splay(b);
185         if(cmd=='C') {
186             gt(c);
187             add_tag(b,c);
188         }else {
189             pt(da[b].num);
190             pc('\n');
191         }
192     }
193 }
194 int main() {
195 #ifdef DEBUG
196     freopen("paint.in","r",stdin);
197     freopen("paint.out","w",stdout);
198 #endif
199     fread(in,1,D,stdin);
200 
201     init();
202     work();
203     
204     return printf(out),0;
205 }

 

posted @ 2015-05-04 23:48  Showson  阅读(166)  评论(0编辑  收藏  举报