这题确实很好.
题解方面,网上有许多不错的题解,所以就不说了.
这题很需要注意细节.
#include<cstdio>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define db long double
#define pii pair<int,int>
#define pb push_back
#define FILE "dealing"
template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
template<class T> inline T squ(T a){return a*a;}
const int maxn=210000+10,mod=10007,base=23;
int read(){
int x=0,f=1,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
struct Node{
int y,next,v;
}e[maxn];int len,linkk[maxn];
void insert(int x,int y,int v){
e[++len].y=y;
e[len].next=linkk[x];
linkk[x]=len;
e[len].v=v;
}
int n,m;
int fa[maxn],sf[maxn],c[maxn][2];
bool isroot(int x){
return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
}
struct node{
int k,b;
node(int k=1,int b=0):k(k),b(b){}
}li[maxn],sum[maxn];
node operator+(const node& a,const node& b){
node c;
c.k=a.k*b.k%mod;
c.b=(a.b*b.k%mod+b.b)%mod;
return c;
}
void updata(int x){
sum[x]=sum[c[x][0]]+li[x]+sum[c[x][1]];
}
void rotate(int x){
int y=fa[x],z=fa[y],d=c[y][1]==x;
if(!isroot(y))c[z][c[z][1]==y]=x;
fa[y]=x;fa[x]=z;if(c[x][d^1])fa[c[x][d^1]]=y;
c[y][d]=c[x][d^1],c[x][d^1]=y;
updata(y);updata(x);
}
void splay(int x){
if(!x)return;
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if(c[y][1]==x^c[z][1]==y)rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x){
for(int t=0;x;t=x,x=fa[x]){
splay(x);
c[x][1]=t;
updata(x);
}
}
int root,vis[maxn];
void dfs(int x,int fa){
vis[x]=1;
for(int i=linkk[x];i;i=e[i].next){
if(e[i].y==fa)continue;
if(!vis[e[i].y])dfs(e[i].y,x);
else root=x;
}
}
int inv[maxn];
int getroot(int x){
access(x);splay(x);
while(c[x][0])x=c[x][0];
return x;
}
int getl(int x){
access(x);splay(x);
x=c[x][0];while(c[x][1])x=c[x][1];
return x;
}
int tk[maxn];
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=read();
up(i,1,n){
li[i].k=read();
fa[i]=read();
li[i].b=read();
sum[i]=li[i];
insert(i,fa[i],1);
insert(fa[i],i,-1);
tk[i]=fa[i];
}
up(i,1,n){
if(vis[i])continue;
root=0;
dfs(i,0);
sf[root]=fa[root];
fa[root]=0;
}
m=read();
inv[0]=inv[1]=1;
for(int i=2;i<mod;i++)inv[i]=(mod-(mod/i)*inv[mod%i]%mod)%mod;
up(i,1,m){
char s;
scanf(" %c",&s);
if(s=='A'){
int x=read();
int root=getroot(x),y=sf[root];
access(y);splay(y);
node b=sum[y];
if(b.k==1){
if(b.b==0)printf("%d\n",-2);
else printf("-1\n");
}
else {
int key=(mod-b.b)%mod*inv[(b.k-1+mod)%mod]%mod;
access(x);splay(x);
printf("%d\n",(sum[x].k*key%mod+sum[x].b)%mod);
}
}
else {
int x=read(),k=read(),p=read(),b=read();
int ro=getroot(x);
li[x]=node(k,b);
updata(x);
if(tk[x]==p)continue;
tk[x]=p;
if(ro==x){
sf[ro]=0;
int ro2=getroot(p);
if(ro2==ro)sf[ro]=p;
else {
access(ro);splay(ro);
fa[ro]=p;
}
}
else {
int w=getl(x);
access(x);splay(w);
c[w][1]=fa[x]=0;updata(w);
int y=sf[ro];
int ro2=getroot(y);
if(ro2!=ro){
access(ro);
splay(ro);
fa[ro]=y;
sf[ro]=0;
}
int ro3=getroot(p);
access(x);
splay(x);
if(ro3!=x)fa[x]=p;
else sf[x]=p;
}
}
}
return 0;
}