标签:
AC的有些艰难,为了学这个下标传递先去水了这道题,其实会了下标传递这就是个LCT模板题..
不过LCT还是比较容易写崩,数据结构毁一生
另外,怎么动态求$node_a$到$node_b$的路径?
void LCA(int noda,int nodb){//noda is LCA Reverse(nodb);access(noda);splay(noda); }
先把$node_b$提到树根,然后打通$node_a$到$root$的路径,再把$node_a$转到链根,显然$node_a$的信息就是到$node_b$的路径
1 //bzoj 2631 2 //by Cydiater 3 //2016.9.14 4 #include <iostream> 5 #include <cstdio> 6 #include <cstring> 7 #include <string> 8 #include <algorithm> 9 #include <queue> 10 #include <map> 11 #include <cstdlib> 12 #include <iomanip> 13 #include <ctime> 14 #include <cmath> 15 using namespace std; 16 #define ll unsigned int 17 #define up(i,j,n) for(int i=j;i<=n;i++) 18 #define down(i,j,n) for(int i=j;i>=n;i--) 19 const int MAXN=1e6+5; 20 const int oo=0x3f3f3f3f; 21 const int mod=51061; 22 inline ll read(){ 23 char ch=getchar();ll x=0,f=1; 24 while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();} 25 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 26 return x*f; 27 } 28 ll LINK[MAXN],len=0,N,M,q[MAXN],top=0,num,nodea,nodeb; 29 char op; 30 struct edge{ 31 int y,next; 32 }e[MAXN<<1]; 33 struct SplayTree{ 34 ll son[2],sum,delta1,delta2,fa,tag,v,siz; 35 }t[MAXN]; 36 namespace solution{ 37 inline bool get(int node){return t[t[node].fa].son[1]==node;} 38 inline void insert(ll x,ll y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;} 39 inline bool isroot(int node){return t[t[node].fa].son[0]!=node&&t[t[node].fa].son[1]!=node;} 40 inline void work(int node,ll d1,ll d2){ 41 if(!node)return; 42 t[node].v=t[node].v*d2+d1;t[node].v%=mod; 43 t[node].sum=t[node].sum*d2+d1*t[node].siz;t[node].sum%=mod; 44 t[node].delta1=t[node].delta1*d2+d1;t[node].delta1%=mod; 45 t[node].delta2*=d2;t[node].delta2%=mod; 46 } 47 inline void updata(int node){ 48 if(node){ 49 t[node].sum=t[node].v;t[node].siz=1; 50 if(t[node].son[0]){t[node].sum+=t[t[node].son[0]].sum;t[node].siz+=t[t[node].son[0]].siz;} 51 if(t[node].son[1]){t[node].sum+=t[t[node].son[1]].sum;t[node].siz+=t[t[node].son[1]].siz;} 52 t[node].sum%=mod; 53 } 54 } 55 inline void downit(int node){ 56 ll d1=t[node].delta1,d2=t[node].delta2,tmp; 57 if(t[node].tag){ 58 t[t[node].son[0]].tag^=1;t[t[node].son[1]].tag^=1; 59 swap(t[node].son[0],t[node].son[1]); 60 } 61 work(t[node].son[0],d1,d2);work(t[node].son[1],d1,d2); 62 t[node].delta1=0;t[node].delta2=1;t[node].tag=0; 63 } 64 void rotate(int node){ 65 int old=t[node].fa,oldf=t[old].fa,which=get(node); 66 if(!isroot(old))t[oldf].son[old==t[oldf].son[1]]=node; 67 t[old].son[which]=t[node].son[which^1];t[t[old].son[which]].fa=old; 68 t[old].fa=node;t[node].son[which^1]=old;t[node].fa=oldf; 69 updata(old);updata(node); 70 } 71 void splay(int node){ 72 top=0;q[++top]=node; 73 for(int i=node;!isroot(i);i=t[i].fa)q[++top]=t[i].fa; 74 down(i,top,1)downit(q[i]); 75 while(!isroot(node)){ 76 int old=t[node].fa,oldf=t[old].fa; 77 if(!isroot(old))rotate(get(node)==get(old)?old:node); 78 rotate(node); 79 } 80 } 81 void access(int node){int tmp=0;while(node){splay(node);t[node].son[1]=tmp;updata(node);tmp=node;node=t[node].fa;}} 82 void Reverse(int node){access(node);splay(node);t[node].tag^=1;} 83 void Link(int noda,int nodb){Reverse(noda);t[noda].fa=nodb;splay(noda);} 84 void Cut(int noda,int nodb){Reverse(noda);access(nodb);splay(nodb);t[nodb].son[0]=t[noda].fa=0;} 85 void LCA(int noda,int nodb){//noda is LCA 86 Reverse(nodb);access(noda);splay(noda); 87 } 88 void dfs(int node,int fa){ 89 t[node].sum=1;t[node].fa=fa;t[node].son[1]=t[node].son[0]=0; 90 t[node].delta1=0;t[node].delta2=1;t[node].v=1;t[node].siz=1; 91 for(int i=LINK[node];i;i=e[i].next)if(e[i].y!=fa)dfs(e[i].y,node); 92 } 93 void init(){ 94 N=read();M=read(); 95 up(i,2,N){ 96 ll x=read(),y=read(); 97 insert(x,y); 98 insert(y,x); 99 } 100 dfs(1,0); 101 } 102 void slove(){ 103 while(M--){ 104 scanf("%c",&op);nodea=read();nodeb=read(); 105 ll de1,de2; 106 if(op==‘*‘){ 107 de1=0;de2=read(); 108 LCA(nodea,nodeb);work(nodea,de1,de2); 109 } 110 if(op==‘+‘){ 111 de1=read();de2=1; 112 LCA(nodea,nodeb);work(nodea,de1,de2); 113 } 114 if(op==‘-‘){ 115 Cut(nodea,nodeb); 116 nodea=read();nodeb=read(); 117 Link(nodea,nodeb); 118 } 119 if(op==‘/‘){ 120 LCA(nodea,nodeb); 121 printf("%u\n",t[nodea].sum); 122 } 123 } 124 } 125 } 126 int main(){ 127 //freopen("input.in","r",stdin); 128 using namespace solution; 129 init(); 130 slove(); 131 return 0; 132 }
标签:
原文地址:http://www.cnblogs.com/Cydiater/p/5876251.html