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 }
原文出处http://www.cnblogs.com/showson/