的确是好题。。。
根本不会,然后copy了PoPoQQQ大爷的代码
反正就是LCT乱搞
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int Mod=10007,N=30005; int n,m,vis[N],cnt,fa[N]; struct Line{ int k,b; Line(){} Line(int ks,int bs){k=ks;b=bs;} friend Line operator+(Line A,Line B){return Line(A.k*B.k%Mod,(B.k*A.b+B.b)%Mod);} int F(int x){return (k*x+b)%Mod;} }; struct Node{ Line v,sum; Node *ch[2],*fa,*spc; Node(int k,int b); void Pushup(); }*root[N],*Null; Node::Node(int k,int b){ch[0]=ch[1]=fa=spc=Null;v=sum=Line(k,b);} void Node::Pushup(){sum=ch[0]->sum+v+ch[1]->sum;} bool Notroot(Node *x){return x->fa->ch[0]==x || x->fa->ch[1]==x;} Node *GetNull(){Node *p=new Node(1,0);p->ch[0]=p->ch[1]=p->fa=p;return p;} void Rotate(Node *x,int kind){ Node *y=x->fa,*z=y->fa; y->ch[!kind]=x->ch[kind]; if(x->ch[kind]!=Null)x->ch[kind]->fa=y; x->fa=z; if(Notroot(y))z->ch[z->ch[1]==y]=x; y->fa=x; x->ch[kind]=y; y->Pushup(); x->Pushup(); } void Splay(Node *x){ while(Notroot(x)){ Node *y=x->fa,*z=y->fa; if(!Notroot(y))Rotate(x,y->ch[0]==x); else { if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);} else if(y->ch[0]==x && z->ch[1]==y){Rotate(x,1);Rotate(x,0);} else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);} else {Rotate(y,0);Rotate(x,0);} } } } void Access(Node *x){for(Node *y=Null;x!=Null;y=x,x=x->fa){Splay(x);x->ch[1]=y;x->Pushup();}} Node *Findroot(Node *x){Access(x);Splay(x);while(x->ch[0]!=Null)x=x->ch[0];return x;} pair<int,int>exgcd(int a,int b){if(!b)return make_pair(1,0);pair<int,int>P=exgcd(b,a%b);return make_pair(P.second,P.first-a/b*P.second);} int Inv(int x){int P=exgcd((x+Mod)%Mod,Mod).first;return (P%Mod+Mod)%Mod;} void DFS(int u){vis[u]=cnt;if(vis[fa[u]]==cnt){root[u]->spc=root[fa[u]];return;}root[u]->fa=root[fa[u]];if(!vis[fa[u]])DFS(fa[u]);} int Query(Node *x){ Node *rt=Findroot(x); Access(rt->spc); Splay(rt->spc); int k=rt->spc->sum.k,b=rt->spc->sum.b; if(k==1 && !(b==0 && x->sum.k==0))return b?-1:-2; Access(x); Splay(x); return x->sum.F((Mod-b)*Inv(k-1)%Mod); } void Modify(Node *x,int k,Node *f,int b){ Node *rt=Findroot(x); x->v.k=k;x->v.b=b;x->Pushup(); if(x==rt)x->spc=Null; else { Access(x); Splay(x); x->ch[0]->fa=Null; x->ch[0]=Null; x->Pushup(); if(Findroot(rt->spc)!=rt){ Access(rt); Splay(rt); rt->fa=rt->spc; rt->spc=Null; } } Access(x); Splay(x); if(Findroot(f)==x){x->spc=f;} else x->fa=f; } int main(){ freopen("2759.in","r",stdin); freopen("2759.out","w",stdout); scanf("%d",&n); Null=GetNull(); for(int i=1;i<=n;i++){ int k,f,b; scanf("%d %d %d",&k,&f,&b); fa[i]=f; root[i]=new Node(k,b); } for(int i=1;i<=n;i++){if(!vis[i]){cnt++;DFS(i);}} scanf("%d",&m); for(int i=1;i<=m;i++){ char s[10]; int x,k,p,b; scanf("%s",s); if(s[0]=='A'){scanf("%d",&x);printf("%d\n",Query(root[x]));} if(s[0]=='C'){scanf("%d %d %d %d",&x,&k,&p,&b);Modify(root[x],k,root[p],b);} } return 0; }