搞了一上午LCT,真是累死了……
以前总觉得LCT高大上不好学不好打,今天打了几遍感觉还可以嘛= =反正现在的水平应付不太难的LCT题也够用了,就这样好了,接下来专心搞网络流。
话说以前一直YY不出来LCT怎么维护边权,多谢sxysxy告诉我要添虚点来把边权转化为点权,感激不尽……
言归正传。
LCT模板题嘛……
区间乘和区间加一遍写对,感觉费了好多rp……
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<vector> 5 #define isroot(x) ((x)->p==null||((x)->p->ch[0]!=(x)&&(x)->p->ch[1]!=(x))) 6 #define dir(x) ((x)==(x)->p->ch[1]) 7 using namespace std; 8 typedef unsigned uint; 9 const int maxn=100010; 10 const uint M=51061u; 11 struct node{ 12 uint data,sm,a,b; 13 int size; 14 node *ch[2],*p; 15 bool rev; 16 node(uint d=0u):data(d),sm(d),a(1u),b(0u),size(1),rev(false){} 17 void add(uint d){ 18 sm+=(uint)size%M*d%M;sm%=M; 19 data+=d;data%=M; 20 b+=d;b%=M; 21 } 22 void mul(uint d){ 23 sm*=d;sm%=M; 24 data*=d;data%=M; 25 b*=d;b%=M; 26 a*=d;a%=M; 27 } 28 void pushdown(){ 29 if(rev){ 30 ch[0]->rev^=true; 31 ch[1]->rev^=true; 32 swap(ch[0],ch[1]); 33 rev=false; 34 } 35 if(a!=1){ 36 ch[0]->mul(a); 37 ch[1]->mul(a); 38 a=1u; 39 } 40 if(b){ 41 ch[0]->add(b); 42 ch[1]->add(b); 43 b=0u; 44 } 45 } 46 void refresh(){ 47 size=ch[0]->size+ch[1]->size+1; 48 sm=ch[0]->sm+ch[1]->sm;sm%=M;sm+=data;sm%=M; 49 } 50 }nodes[maxn],*null=nodes; 51 void dfs(int); 52 void add(node*,node*,uint); 53 void mul(node*,node*,uint); 54 uint qsum(node*,node*); 55 node *access(node*); 56 void makeroot(node*); 57 void link(node*,node*); 58 void cut(node*,node*); 59 void splay(node*); 60 void rot(node*,int); 61 vector<int>G[maxn]; 62 int n,m,prt[maxn]={0},x,y; 63 uint d; 64 char c; 65 int main(){ 66 freopen("nt2012_wym_tree.in","r",stdin); 67 freopen("nt2012_wym_tree.out","w",stdout); 68 null->ch[0]=null->ch[1]=null->p=null; 69 null->size=0; 70 scanf("%d%d",&n,&m); 71 for(int i=1;i<n;i++){ 72 scanf("%d%d",&x,&y); 73 G[x].push_back(y); 74 G[y].push_back(x); 75 } 76 dfs(1); 77 for(int i=1;i<=n;i++){ 78 nodes[i]=node(1); 79 nodes[i].ch[0]=nodes[i].ch[1]=null; 80 nodes[i].p=nodes+prt[i]; 81 } 82 while(m--){ 83 scanf(" %c%d%d",&c,&x,&y); 84 if(c=='+'){ 85 scanf("%u",&d); 86 add(nodes+x,nodes+y,d); 87 } 88 else if(c=='-'){ 89 cut(nodes+x,nodes+y); 90 scanf("%d%d",&x,&y); 91 link(nodes+x,nodes+y); 92 } 93 else if(c=='*'){ 94 scanf("%u",&d); 95 mul(nodes+x,nodes+y,d); 96 } 97 else if(c=='/')printf("%u\n",qsum(nodes+x,nodes+y)); 98 } 99 return 0; 100 } 101 void dfs(int x){ 102 for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=prt[x]){ 103 prt[G[x][i]]=x; 104 dfs(G[x][i]); 105 } 106 } 107 void add(node *x,node *y,uint d){ 108 makeroot(x); 109 access(y)->add(d); 110 } 111 void mul(node *x,node *y,uint d){ 112 makeroot(x); 113 access(y)->mul(d); 114 } 115 uint qsum(node *x,node *y){ 116 makeroot(x); 117 return access(y)->sm; 118 } 119 node *access(node *x){ 120 node *y=null; 121 while(x!=null){ 122 splay(x); 123 x->ch[1]=y; 124 (y=x)->refresh(); 125 x=x->p; 126 } 127 return y; 128 } 129 void makeroot(node *x){ 130 access(x); 131 splay(x); 132 x->rev^=true; 133 } 134 void link(node *x,node *y){ 135 makeroot(x); 136 x->p=y; 137 } 138 void cut(node *x,node *y){ 139 makeroot(x); 140 access(y); 141 splay(y); 142 x->p=null; 143 y->ch[0]=null; 144 y->refresh(); 145 } 146 void splay(node *x){ 147 x->pushdown(); 148 while(!isroot(x)){ 149 if(!isroot(x->p))x->p->p->pushdown(); 150 x->p->pushdown(); 151 x->pushdown(); 152 if(isroot(x->p)){ 153 rot(x->p,dir(x)^1); 154 break; 155 } 156 if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1); 157 else rot(x->p,dir(x)^1); 158 rot(x->p,dir(x)^1); 159 } 160 } 161 void rot(node *x,int d){ 162 node *y=x->ch[d^1]; 163 x->ch[d^1]=y->ch[d]; 164 if(y->ch[d]!=null)y->ch[d]->p=x; 165 y->p=x->p; 166 if(!isroot(x))x->p->ch[dir(x)]=y; 167 y->ch[d]=x; 168 x->p=y; 169 x->refresh(); 170 y->refresh(); 171 }