bzoj2631: tree lct

要打mul和add的lct

50000+的mod用unsigned int好了TAT

(坑爹没打pc(‘\n‘);(静态)调了好久,样例竟然只输出一个,orz,也不提示PE T_T)

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<cstdio>
  6
  7 using namespace std;
  8
  9 const int D=15000000;
 10 char in[D],out[100010*10],*I=in,*O=out;
 11 #define gc (*I++)
 12 #define pc(x) ((*O++)=x)
 13 template <typename Q>
 14 void gt(Q&x) {
 15     static char c,f;
 16     for(c=gc,f=0;!isdigit(c);c=gc)if(c==‘-‘) f=1;
 17     for(x=0;isdigit(c);c=gc) x=x*10+c-‘0‘;
 18     f && (x=-x);
 19 }
 20 template <typename Q>
 21 void pt(Q x){
 22     static char stk[20];
 23     static int top;
 24     top=0;
 25     if(x==0) pc(‘0‘);
 26     for(;x;x/=10) stk[++top] = x%10+‘0‘;
 27     for(;top;top--) pc(stk[top]);
 28 }
 29
 30 typedef unsigned ll;
 31 const int Maxn=100010,Mod=51061;
 32 int n,m;
 33 ll w[Maxn],tagm[Maxn],taga[Maxn],sz[Maxn];
 34 int ch[Maxn][2],p[Maxn],flip[Maxn],sum[Maxn];
 35
 36 void update(int x){
 37     if(x==0) return;
 38     int&l=ch[x][0],&r=ch[x][1];
 39     sum[x] = (sum[l] + sum[r] + w[x])%Mod;
 40     sz[x] = (sz[l] + sz[r] + 1)%Mod;
 41 }
 42
 43 void add_tag(int x,ll a,ll m){
 44     if(!x) return;
 45     sum[x] = (sum[x]*m+a*sz[x])%Mod;
 46     w[x] = (w[x]*m+a)%Mod;
 47     tagm[x] = tagm[x]*m%Mod;
 48     taga[x] = (taga[x]*m+a)%Mod;
 49 }
 50
 51 /*void tag_mul(int x,ll _v) {
 52     (sum[x]*=_v)%=Mod;
 53     (w[x]*=_v)%=Mod;
 54     (tagm[x]*=_v)%=Mod;
 55     (taga[x]*=_v)%=Mod;
 56 }
 57
 58 void tag_add(int x,ll _v) {
 59     (sum[x]+=(sz[x]*_v)%Mod)%=Mod;
 60     (w[x]+=_v)%=Mod;
 61     (taga[x]+=_v)%=Mod;
 62 }*/
 63
 64 bool isroot(int x) {
 65     return ch[p[x]][0]!=x && ch[p[x]][1]!=x;
 66 }
 67
 68 void down(int x) {
 69     int &l=ch[x][0],&r=ch[x][1];
 70     if(flip[x]) {
 71         swap(l,r);
 72         flip[l]^=1;
 73         flip[r]^=1;
 74         flip[x]=0;
 75     }
 76     /*if(tagm[x]!=1) {
 77         for(int i=0;i<2;i++)if(ch[x][i])tag_mul(ch[x][i],tagm[x]);
 78         tagm[x]=1;
 79     }
 80     if(taga[x]!=0) {
 81         for(int i=0;i<2;i++)if(ch[x][i])tag_add(ch[x][i],taga[x]);
 82         taga[x]=0;
 83     }*/
 84     ll&a=taga[x],&m=tagm[x];
 85     if(a!=0 || m!=1) {
 86         add_tag(l,a,m);
 87         add_tag(r,a,m);
 88         a=0;m=1;
 89     }
 90 }
 91
 92 void rotate(int x){
 93     int y=p[x],z=p[y];
 94     int l=ch[y][1]==x,r=l^1;
 95     if(!isroot(y)){
 96         ch[z][ch[z][1]==y]=x;
 97     }
 98     p[y]=x;
 99     p[ch[x][r]]=y;
100     p[x]=z;
101
102     ch[y][l]=ch[x][r];
103     ch[x][r]=y;
104
105     update(y);
106 //    update(x);
107 }
108
109 int stk[Maxn],top;
110 void splay(int x){
111     stk[top=1]=x;
112     for(int t=x;!isroot(t);stk[++top]=t=p[t]);
113     for(;top;top--) down(stk[top]);
114     for(;!isroot(x);){
115         int y=p[x],z=p[y];
116         if(!isroot(y)) {
117             if( (ch[y][0]==x) ^ (ch[z][0]==y)) rotate(x);
118             else rotate(y);
119         }
120         rotate(x);
121     }
122     update(x);
123 }
124
125 void access(int x) {
126     for(int t=0;x;x=p[t=x]){
127         splay(x);
128         ch[x][1]=t;
129         update(x);
130     }
131 }
132
133 void newroot(int x) {
134     access(x);
135     splay(x);
136     flip[x]^=1;
137 }
138
139 inline void n_as(int u,int v){
140     newroot(u);
141     access(v);
142     splay(v);
143 }
144
145 void Cut(int x,int y) {
146     n_as(x,y);
147     ch[y][0]=p[x]=0;
148     update(x);
149 }
150
151 void Link(int x,int y) {
152     newroot(x);
153     p[x]=y;
154 }
155
156 int en[Maxn*2],next[Maxn*2],fir[Maxn];
157 void Add(int from,int to) {
158     static int tot=0;
159     en[++tot]=to;
160     next[tot]=fir[from];
161     fir[from]=tot;
162 }
163
164 void BFS(int u) {
165     int *q=stk,ql=0,qr=0;
166     q[++qr]=u;
167     for(int x;ql<qr;){
168         x=q[++ql];
169         for(int k=fir[x];k;k=next[k]){
170             int v=en[k];
171             if(v==p[x]) continue;
172             p[v]=x;
173             q[++qr]=v;
174         }
175     }
176 }
177
178 void init(){
179     gt(n),gt(m);
180     for(int u,v,i=1;i<n;i++) {
181         gt(u),gt(v);
182 //        Add(u,v),Add(v,u);
183         Link(u,v);
184     }
185 //    BFS(1);
186     tagm[0]=1;
187     for(int i=1;i<=n;i++) sz[i]=sum[i]=tagm[i]=w[i]=1;
188 }
189
190 void work() {
191     char c;
192     ll u,v,d;
193     /*printf("round%d:\n",0);
194         for(int i=1;i<=n;i++) {
195             printf("%d :p=%d,ch=(%d,%d),w=%d,taga=%d,tagm=%d\n",i,p[i],ch[i][0],ch[i][1],w[i],taga[i],tagm[i]);
196         }*/
197     for(int i=1;i<=m;i++) {
198         for(;;) {
199             c=gc;
200             if(c==‘+‘) {
201                 gt(u),gt(v),gt(d);
202                 n_as(u,v);
203 //                tag_add(v,d);
204                 add_tag(v,d,1);
205                 break;
206             }if(c==‘-‘) {
207                 gt(u),gt(v);
208                 Cut(u,v);
209                 gt(u),gt(v);
210                 Link(u,v);
211                 break;
212             }if(c==‘*‘) {
213                 gt(u),gt(v),gt(d);
214                 n_as(u,v);
215                 add_tag(v,0,d);
216 //                tag_mul(v,d);
217                 break;
218             }if(c==‘/‘){
219                 gt(u),gt(v);
220                 n_as(u,v);
221                 pt(sum[v]);
222                 pc(‘\n‘);
223                 break;
224             }
225         }
226         /*printf("round%d:\n",i);
227         for(int i=1;i<=n;i++) {
228             printf("%d :p=%d,ch=(%d,%d),w=%d,taga=%d,tagm=%d,sum=%d\n",i,p[i],ch[i][0],ch[i][1],w[i],taga[i],tagm[i],sum[i]);
229         }*/
230     }
231 }
232
233 int main() {
234 #ifdef DEBUG
235     freopen("in.txt","r",stdin);
236 //    freopen("out.txt","w",stdout);
237 #endif
238     fread(in,1,D,stdin);
239
240     init();
241     work();
242
243     return printf(out),0;
244 }
时间: 2024-10-22 12:11:10

bzoj2631: tree lct的相关文章

HDU4718 The LCIS on the Tree(LCT)

又是一枚LCT,写一发加深一下对LCT的理解.本题的坑爹之处就在于,它实在是太坑爹了.询问的是树路径上的最长连续上升的子串,考验的是怎么样去维护.一开始的想法是维护三个变量 ls,rs,mxl,分别表示左起最长上升,右末最长上升,以及总的最长上升,那么最长上升一定是可以在下面的条件下求到的, mxl=max(ch[0]->mxl,ch[1]->mxl) 以及 令temp=1 存一下左右区间的左右lval,rval, if val>ch[0]->rval temp+=ch[0]-&g

BZOJ2631 tree(伍一鸣) LCT 秘制标记

这个题一看就是裸地LCT嘛,但是我wa了好几遍,这秘制标记...... 注意事项:I.*对+有贡献 II.先下传*再下传+(因为我们已经维护了+,不能再让*对+产生贡献)III.维护+用到size #include<cstdio> #include<cstring> #include<iostream> #define MAXN 100005 #define P 51061 using namespace std; inline unsigned int read()

BZOJ 2631: tree( LCT )

LCT...略麻烦... -------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #define

hdu5398 GCD Tree(lct)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud GCD Tree Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 84    Accepted Submission(s): 38 Problem Description Teacher Mai has a graph w

[BZOJ3282]Tree(LCT)

3282: Tree Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 2350  Solved: 1104[Submit][Status][Discuss] Description 给定N个点以及每个点的权值,要你处理接下来的M个操作. 操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和. 保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连

BZOJ 3282: Tree [LCT]

3282: Tree Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1677  Solved: 744[Submit][Status][Discuss] Description 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接.

spoj 375 query on a tree LCT

这道题是树链剖分的裸题,正在学LCT,用LCT写了,发现LCT代码比树链剖分还短点(但我的LCT跑极限数据用的时间大概是kuangbin大神的树链剖分的1.6倍,所以在spoj上是850ms卡过的). 收获: 1.边转换成点(即若存在边(u,v),则新加一个点z代表边,将z连接u和v,z的点权就是(u,v)的边权,非边点的权设为-oo),然后对边权的统计就变成了对点权的统计(这是LCT中处理边信息的通法之一). 2.若要连接两个点u,v,先让它们分别称为根,然后将其中一个的path-parent

BZOJ2631: tree

2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1486  Solved: 515[Submit][Status] Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一:+ u v c:将u到v的路径上的点的权值都加上自然数c:- u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树:* u v c:将u到v的

【bzoj3282】Tree LCT

题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接. 2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在. 3:后接两个整数(x,y),代表将点X上的权值变成Y. 输入 第1行两个整数,分别为N和M,代表点数和操作数. 第2行到第N+1行,每行一个整