bzoj2759 -- LCT

来源:互联网 发布:php开发网站 编辑:程序博客网 时间:2024/04/29 23:08

神题

题解

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 30010#define M 10007struct Node{    int k,b;    Node(int k=0,int b=0):k(k),b(b){}    Node operator + (Node a){        return Node(k*a.k%M,(a.k*b+a.b)%M);    }}a[N],c[N];int f[N],sf[N],ch[N][2];int i,j,k,n,m,p,v[N],Q,x,y,z;bool b[N];char s[3];inline void Dfs(int x){    v[x]=i;    if(!v[f[x]])Dfs(f[x]);else    if(v[f[x]]==i)sf[x]=f[x],f[x]=0;}inline bool Get(int x){    return ch[f[x]][1]==x;}inline void Up(int x){    c[x]=c[ch[x][0]]+a[x]+c[ch[x][1]];}inline void Rotate(int x){    int y=f[x];bool d=Get(x);    if(b[y])b[x]=1,b[y]=0;else ch[f[y]][Get(y)]=x;    ch[y][d]=ch[x][d^1];f[ch[y][d]]=y;    f[x]=f[y];f[y]=x;ch[x][d^1]=y;Up(y);}inline void Splay(int x){    for(;!b[x];Rotate(x))    if(!b[f[x]])Rotate(Get(x)==Get(f[x])?f[x]:x);    Up(x);}inline void Access(int x){    int y=0;    while(x){        Splay(x);        b[ch[x][1]]=1;ch[x][1]=y;b[y]=0;        Up(y=x);x=f[x];    }}inline void mr(int x){    Access(x);Splay(x);}inline int Find(int x){    mr(x);    int t=x;    for(;ch[t][0];t=ch[t][0]);    return t;}inline void Ex_Gcd(int a,int b,int& x,int& y){    if(!b){x=1;y=0;return;}    Ex_Gcd(b,a%b,y,x);    y-=a/b*x;}inline int Query(int x){    int t=sf[Find(x)];    mr(t);    if(c[t].k==1){        if(!c[t].b)return -2;        return -1;    }    Ex_Gcd((c[t].k-1+M)%M,M,y,z);    y=(y*(M-c[t].b)%M+M)%M;    mr(x);    return (y*c[x].k+c[x].b)%M;}inline void Update(int x,int y,Node z){    int r=Find(x);    a[x]=z;Up(x);    if(x==r)sf[x]=0;else{        mr(x);        f[ch[x][0]]=0;b[ch[x][0]]=1;ch[x][0]=0;        Up(x);        if(Find(sf[r])!=r)mr(r),f[r]=sf[r],sf[r]=0;    }    mr(x);    if(Find(y)==x)sf[x]=y;else f[x]=y;}int main(){    scanf("%d",&n);c[0].k=1;    for(i=1;i<=n;i++)scanf("%d%d%d",&a[i].k,&f[i],&a[i].b),b[i]=1,c[i]=a[i];    for(i=1;i<=n;i++)if(!v[i])Dfs(i);    scanf("%d",&Q);    while(Q--){        scanf("%s%d",s,&x);        if(s[0]=='A')printf("%d\n",Query(x));else        scanf("%d%d%d",&y,&k,&z),Update(x,k,Node(y,z));    }    return 0;}
原创粉丝点击