省选膜你33
记不太清了,是昨天的模拟赛,昨晚很晚很晚才改完题啊
最近有点消极怠工,今天好不容易才把最后一题改过去......
开场看的第一题,观察出来好多性质,但是无法用线段树维护,所以就完蛋了
第二题吧,看了一会发现ntt可以优化第一步卷积,第二步是乘法,不会了
第三题只写了暴力,还没调对
T1 传教
就是给你一个序列,要把这个序列异或成0序列
于是我们可以先用差分求出来初始的时候每一个长度为k的段需要异或多少,将这个值记录在每一段的第一个位置
这样我们每次只需要统计这样的值不为零的个数就好了,无解的情况就是最后k-1个数有值,因为块长使得最后是不能有数的
开始考虑怎样动态维护这个东东,发现每次修改的是x,x+1的所有同余后缀,将这些数异或上更改的值
那么我们就有了一个\(k>=\sqrt{n}\)的做法,每次暴力往后跳并更新答案,这样复杂度是\(\mathcal{O(n\sqrt{n})}\)
我们开始考虑\(k<=\sqrt{n}\)怎么办,之前都是暴力的,然而这次闷头乱撞了,啥也不是
于是我们分块维护桶,每次就是\(\sqrt{n}\),注意这里我们是对于每个同余分开考虑,但是块长仍位\(\sqrt{n}\),这样可以保证复杂度
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=2e5+5;
int n,k,q,sq,a[N],b[N],c[N];
int cf[N],an[N],ans,sum;
void print(){
if(sum)printf("-1\n");
else printf("%d\n",ans);
}
void spj(){
fo(i,1,n)if(c[i])ans++;
print();
while(q--){
char ch[5];scanf("%s",ch+1);
int x=read(),y=read();
if(ch[1]=='a')y^=a[x];
if(ch[1]=='b')y^=b[x];
if(c[x]==y)ans--;
if(!c[x])ans++;
print();
if(ch[1]=='a')a[x]^=y;
if(ch[1]=='b')b[x]^=y;
c[x]^=y;
// fo(i,1,n)cerr<<a[i]<<" ";cerr<<endl;
}
}
void spj2(){
print();
while(q--){
char ch[5];scanf("%s",ch+1);
int x=read(),y=read();
if(ch[1]=='a')y^=a[x];
if(ch[1]=='b')y^=b[x];
for(int i=x;i<=n;i+=k){
if(an[i]==y){
ans--;
if(i+k-1>n)sum--;
}
if(!an[i]){
ans++;
if(i+k-1>n)sum++;
}
an[i]^=y;
}
for(int i=x+1;i<=n;i+=k){
if(an[i]==y){
ans--;
if(i+k-1>n)sum--;
}
if(!an[i]){
ans++;
if(i+k-1>n)sum++;
}
an[i]^=y;
}
print();
if(ch[1]=='a')a[x]^=y;
if(ch[1]=='b')b[x]^=y;
c[x]^=y;
}
}
vector<int> vec[455];
vector<int> buc[455][455];
int tag[455][455],sm[455],bl[N],la[N],ra[N];
void change(int x,int p,int y){
p=(p-x)/k;
// cerr<<"change "<<x<<" "<<p<<" "<<y<<" "<<bl[p]<<" "<<sm[x]<<endl;
if(bl[p]<=sm[x]){
fo(i,la[bl[p]],ra[bl[p]]){
buc[x][bl[p]][vec[x][i]]--;
vec[x][i]^=tag[x][bl[p]];
buc[x][bl[p]][vec[x][i]]++;
}
tag[x][bl[p]]=0;
fo(i,p,ra[bl[p]]){
buc[x][bl[p]][vec[x][i]]--;
if(vec[x][i]==0)ans++;
if(vec[x][i]==y)ans--;
vec[x][i]^=y;
buc[x][bl[p]][vec[x][i]]++;
}
}
fo(i,bl[p]+1,sm[x]){
ans+=buc[x][i][tag[x][i]];
if(ra[i]==(int)vec[x].size()-1){
if(vec[x][ra[i]]^tag[x][i]==0)sum++;
if(vec[x][ra[i]]^tag[x][i]==y)sum--;
}
tag[x][i]^=y;
ans-=buc[x][i][tag[x][i]];
}
fo(i,max(sm[x]*sq+sq,p),(int)vec[x].size()-1){
if(vec[x][i]==0){
ans++;
if(i+1==vec[x].size()&&x!=n%k+1)sum++;
}
if(vec[x][i]==y){
ans--;
if(i+1==vec[x].size()&&x!=n%k+1)sum--;
}
vec[x][i]^=y;
}
}
signed main(){
freopen("mission.in","r",stdin);
freopen("mission.out","w",stdout);
n=read();k=read();q=read();sq=sqrt(n);
fo(i,1,n)a[i]=read();
fo(i,1,n)b[i]=read();
fo(i,1,n)c[i]=a[i]^b[i];
if(k==1)return spj(),0;
fo(i,1,n){
cf[i]^=cf[i-1];
an[i]=c[i]^cf[i];
cf[i]^=an[i];
cf[i+k]^=an[i];
if(i+k-1>n&&an[i])sum++;
if(an[i])ans++;
}
if(k>=sq)return spj2(),0;
fo(i,0,n)bl[i]=i/sq;
fo(i,0,n)la[i]=i*sq,ra[i]=i*sq+sq-1;
fo(i,1,k){sm[i]=-1;
for(int j=i;j<=n;j+=k)vec[i].push_back(an[j]);
fo(j,0,n){
if(j*sq+sq-1>=vec[i].size())continue;
buc[i][j].resize(1<<15);sm[i]=j;
fo(k,j*sq,j*sq+sq-1)buc[i][j][vec[i][k]]++;
}
// cerr<<sm[i]<<endl;
}
// fo(i,1,n)cerr<<an[i]<<" ";cerr<<endl;
// cerr<<ans<<" "<<sum<<endl;
print();
while(q--){
char ch[5];scanf("%s",ch+1);
int x=read(),y=read();
if(ch[1]=='a')y^=a[x];
if(ch[1]=='b')y^=b[x];
change((x-1)%k+1,x,y);
change(x%k+1,x+1,y);
// fo(i,1,n)cout<<(vec[(i-1)%k+1][(i-1)/k])<<" ";cerr<<endl;
// cerr<<ans<<" ";
print();
if(ch[1]=='a')a[x]^=y;
if(ch[1]=='b')b[x]^=y;
c[x]^=y;
}
return 0;
}
T2 方程
考场上维护了a+b,乘法不会了,原根就行了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1<<20;
const int mod=998244353;
int ksm(int x,int y,int mo=mod){
int ret=1;
while(y){
if(y&1)ret=ret*x%mo;
x=x*x%mo;y>>=1;
}return ret;
}
int af[N],w[N],lim,len;
void ntt(int *a,int lim){
fo(i,0,lim-1)if(af[i]>i)swap(a[i],a[af[i]]);
for(int t=lim>>1,d=1;d<lim;d<<=1,t>>=1)
for(int i=0;i<lim;i+=(d<<1))
fo(j,0,d-1){
int tmp=a[i+j+d]*w[t*j]%mod;
a[i+j+d]=(a[i+j]-tmp+mod)%mod;
a[i+j]=(a[i+j]+tmp)%mod;
}
}
int p,g,n,m,ans;
int a[N],b[N],c[N];
void mul(int *x,int *y,int *z,int mo=p){
fo(i,0,p-1)a[i]=x[i],b[i]=y[i];
for(lim=1,len=0;lim<2*p;lim<<=1,len++);
fo(i,0,lim-1)af[i]=(af[i>>1]>>1)|((i&1)<<(len-1));
w[0]=1;w[1]=ksm(3,(mod-1)/lim);
fo(i,2,lim-1)w[i]=w[i-1]*w[1]%mod;
ntt(a,lim);ntt(b,lim);
w[0]=1;w[1]=ksm(w[1],mod-2);
fo(i,2,lim-1)w[i]=w[i-1]*w[1]%mod;
fo(i,0,lim-1)c[i]=a[i]*b[i]%mod;
ntt(c,lim);int iv=ksm(lim,mod-2);
fo(i,0,lim-1)z[i]=0;
fo(i,0,lim-1)z[i%mo]=(z[i%mo]+c[i]*iv)%mod,a[i]=b[i]=c[i]=0;
}
int pr[N],cnt,phi[N],mn[N];bool vis[N];
void init(){
fo(i,2,200000){
if(!vis[i])pr[++cnt]=i,phi[i]=i-1,mn[i]=cnt;
for(int j=1;j<=cnt&&i*pr[j]<=200000;j++){
vis[i*pr[j]]=true;
if(i%pr[j]==0){phi[i*pr[j]]=phi[i]*pr[j];mn[i*pr[j]]=j;break;}
else phi[i*pr[j]]=phi[i]*(pr[j]-1),mn[i*pr[j]]=j;
}
}
}
int ji[N],cj;
void prime(int x){cj=0;
while(x!=1){
if(mn[x]==ji[cj]){x/=pr[mn[x]];continue;}
ji[++cj]=mn[x];x/=pr[mn[x]];
}
}
bool jud(int x){
prime(phi[p]);
if(ksm(x,phi[p],p)!=1)return false;
fo(i,1,cj)if(ksm(x,phi[p]/pr[ji[i]],p)==1)return false;
return true;
}
int findrt(){fo(i,1,p)if(jud(i))return i;}
int ta[N],tb[N],ab[N],tc[N],ia[N],ic[N],pc[N],ys[N];
signed main(){
freopen("equation.in","r",stdin);
freopen("equation.out","w",stdout);
p=read();n=read();m=read();
fo(i,1,n)ta[read()]=1;
fo(i,1,m)tb[(read()+1)%p]=true;
mul(ta,ta,ab);init();g=findrt();
// fo(i,0,p-1)cerr<<ab[i]<<" ";cerr<<endl;
int now=1;fo(i,0,p-2)ys[now]=i,now=now*g%p;
fo(i,1,p-1)ia[ys[ksm(i,p-2,p)]]+=ab[i];
fo(i,0,p-2)ia[i]%=mod;//cerr<<ia[i]<<" ";cerr<<endl;
fo(i,1,p-1)tc[ys[i]]+=ta[i];
fo(i,0,p-2)tc[i]%=mod;//cerr<<tc[i]<<" ";cerr<<endl;
mul(ia,tc,ic,p-1);
fo(i,0,p-2)pc[ksm(g,i,p)]+=ic[i];
fo(i,0,p-1){
int iv=ksm(i,p-2,p),now=(p-(i+iv*iv)%p)%p;
if(!tb[now])continue;
ans=(ans+pc[i])%mod;
}
printf("%lld",ans);
}
T3 移花接木
挺复杂的题,看题解+问同学,搞了好久呢
主要是用递归,这递归的题难起来也是啥也不会啊,还要构造函数
发现就是要求每个点到距离他最大深度的点的距离和
我们维护每个树的直径,然后我们需要求距离操作,而这个可以递归求,有用的点只有端点和直径端点
然后构造函数,按着题解上说的干就行了,大致是构造一个距离和函数,仍然递归去做
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=155;
const int mod=998244353;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;y>>=1;
}return ret;
}
int m;struct TREE{int n,ta,tb,x,y,s0,s1;}tr[N];
struct DM{
int id,x,y;DM(){}DM(int a,int b,int c){id=a;x=b;y=c;}
bool operator < (DM a)const{
if(id!=a.id)return id<a.id;
if(x!=a.x)return x<a.x;
return y<a.y;
}
};map<DM,int> dm;
int D(int id,int x,int y){
if(id==0||x==y)return 0;if(x>y)swap(x,y);
if(dm.find(DM(id,x,y))!=dm.end())return dm[DM(id,x,y)];int ret;
if(y<=tr[tr[id].ta].n)ret=D(tr[id].ta,x,y);
else if(x<=tr[tr[id].ta].n&&y>tr[tr[id].ta].n)ret=D(tr[id].ta,x,tr[id].x)+D(tr[id].tb,tr[id].y,y-tr[tr[id].ta].n)+1;
else if(x>tr[tr[id].ta].n)ret=D(tr[id].tb,x-tr[tr[id].ta].n,y-tr[tr[id].ta].n);
return dm[DM(id,x,y)]=ret;
}
struct FM{
int id,s,t,d;FM(){}FM(int a,int b,int c,int e){id=a;s=b;t=c;d=e;}
bool operator < (FM a)const{
if(id!=a.id)return id<a.id;
if(s!=a.s)return s<a.s;
if(t!=a.t)return t<a.t;
return d<a.d;
}
};map<FM,int> fm;
int F(int id,int s,int t,int d){
if(id==0)return 0;
if(fm.find(FM(id,s,t,d))!=fm.end())return fm[FM(id,s,t,d)];
int ret,u=tr[id].x,v=tr[id].y+tr[tr[id].ta].n,ta=tr[id].ta,tb=tr[id].tb;
if(D(id,s,u)<D(id,s,v)){
int dst=D(id,s,t),dsu=D(id,s,u),dtu=D(id,t,u);
if(dst+dtu==dsu&&t<=tr[ta].n)ret=(F(ta,s,t,d)+((dsu+1-d)%mod)*(tr[tb].n%mod)%mod+F(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
else if(dsu+dst==dtu&&t<=tr[ta].n&&d)ret=F(ta,s,t,d);
else if(dsu+dtu==dst&&t>tr[ta].n){
if(d<=dsu)ret=(F(ta,s,u,d)+((dsu+1-d)%mod)*(tr[tb].n%mod)%mod+F(tb,v-tr[ta].n,t-tr[ta].n,0))%mod;
else ret=F(tb,v-tr[ta].n,t-tr[ta].n,d-dsu-1);
}else if(t<=tr[ta].n){int al=(dsu+dst+dtu)/2;
if(d+dtu<=al)ret=(F(ta,s,t,d)+((dsu+1-d)%mod)*(tr[tb].n%mod)%mod+F(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
else ret=F(ta,s,t,d);
}
}else {
int dst=D(id,s,t),dsv=D(id,s,v),dtv=D(id,t,v);
if(dst+dtv==dsv&&t>tr[ta].n)ret=(F(tb,s-tr[ta].n,t-tr[ta].n,d)+((dsv+1-d)%mod)*(tr[ta].n%mod)%mod+F(ta,u,u,0))%mod;
else if(dsv+dst==dtv&&t>tr[ta].n&&d)ret=F(tb,s-tr[ta].n,t-tr[ta].n,d);
else if(dsv+dtv==dst&&t<=tr[ta].n){
if(d<=dsv)ret=(F(tb,s-tr[ta].n,v-tr[ta].n,d)+((dsv+1-d)%mod)*(tr[ta].n%mod)%mod+F(ta,u,t,0))%mod;
else ret=F(ta,u,t,d-dsv-1);
}else if(t>tr[ta].n){
int al=(dsv+dst+dtv)/2;
if(d+dtv<=al)ret=(F(tb,s-tr[ta].n,t-tr[ta].n,d)+((dsv+1-d)%mod)*(tr[ta].n%mod)%mod+F(ta,u,u,0))%mod;
else ret=F(tb,s-tr[ta].n,t-tr[ta].n,d);
}
}return fm[FM(id,s,t,d)]=ret%mod;
}
struct GM{
int id,s,t,d;GM(){}GM(int a,int b,int c,int e){id=a;s=b;t=c;d=e;}
bool operator < (GM a)const{
if(id!=a.id)return id<a.id;
if(s!=a.s)return s<a.s;
if(t!=a.t)return t<a.t;
return d<a.d;
}
};
map<GM,int> gm;
int G(int id,int s,int t,int d){
if(id==0)return 1;if(gm.find(GM(id,s,t,d))!=gm.end())return gm[GM(id,s,t,d)];
int ret,u=tr[id].x,v=tr[id].y+tr[tr[id].ta].n,ta=tr[id].ta,tb=tr[id].tb;
if(D(id,s,u)<D(id,s,v)){
int dst=D(id,s,t),dsu=D(id,s,u),dtu=D(id,t,u);
if(dst+dtu==dsu&&t<=tr[ta].n)ret=(G(ta,s,t,d)+G(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
else if(dsu+dst==dtu&&t<=tr[ta].n&&d)ret=G(ta,s,t,d);
else if(dsu+dtu==dst&&t>tr[ta].n){
if(d<=dsu)ret=(G(ta,s,u,d)+G(tb,v-tr[ta].n,t-tr[ta].n,0))%mod;
else ret=G(tb,v-tr[ta].n,t-tr[ta].n,d-dsu-1);
}else if(t<=tr[ta].n){
int al=(dsu+dst+dtu)/2;
if(d+dtu<=al)ret=(G(ta,s,t,d)+G(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
else ret=G(ta,s,t,d);
}
}else {
int dst=D(id,s,t),dsv=D(id,s,v),dtv=D(id,t,v);
if(dst+dtv==dsv&&t>tr[ta].n)ret=(G(tb,s-tr[ta].n,t-tr[ta].n,d)+G(ta,u,u,0))%mod;
else if(dsv+dst==dtv&&t>tr[ta].n&&d)ret=G(tb,s-tr[ta].n,t-tr[ta].n,d);
else if(dsv+dtv==dst&&t<=tr[ta].n){
if(d<=dsv)ret=(G(tb,s-tr[ta].n,v-tr[ta].n,d)+G(ta,u,t,0))%mod;
else ret=G(ta,u,t,d-dsv-1);
}else if(t>tr[ta].n){
int al=(dsv+dst+dtv)/2;
if(d+dtv<=al)ret=(G(tb,s-tr[ta].n,t-tr[ta].n,d)+G(ta,u,u,0))%mod;
else ret=G(tb,s-tr[ta].n,t-tr[ta].n,d);
}
}return gm[GM(id,s,t,d)]=ret%mod;
}
signed main(){
freopen("link.in","r",stdin);
freopen("link.out","w",stdout);
m=read();tr[0].n=1;tr[0].s0=tr[0].s1=1;
fo(i,1,m){
tr[i].ta=read();tr[i].tb=read();
tr[i].x=read();tr[i].y=read();
tr[i].n=tr[tr[i].ta].n+tr[tr[i].tb].n;
int ns0,ns1,zj=0,now;
now=D(i,tr[tr[i].ta].s0,tr[tr[i].ta].s1);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s0,ns1=tr[tr[i].ta].s1;
now=D(i,tr[tr[i].tb].s0+tr[tr[i].ta].n,tr[tr[i].tb].s1+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].tb].s0+tr[tr[i].ta].n,ns1=tr[tr[i].tb].s1+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s0,tr[tr[i].tb].s0+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s0,ns1=tr[tr[i].tb].s0+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s0,tr[tr[i].tb].s1+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s0,ns1=tr[tr[i].tb].s1+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s1,tr[tr[i].tb].s0+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s1,ns1=tr[tr[i].tb].s0+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s1,tr[tr[i].tb].s1+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s1,ns1=tr[tr[i].tb].s1+tr[tr[i].ta].n;
tr[i].s0=ns0;tr[i].s1=ns1;int ans=0;
if(zj&1){
ans=(F(i,ns0,ns1,zj+1>>1)+F(i,ns1,ns0,zj+1>>1)+(tr[i].n%mod)*((zj+1>>1)%mod)%mod)%mod;
printf("%lld\n",ans);
}
else {
int tmp=G(i,ns0,ns1,zj>>1)%mod;
ans=(F(i,ns0,ns1,zj>>1)+tmp*((zj>>1)%mod))%mod;
ans=(ans+F(i,ns1,ns0,(zj>>1)+1)+((zj>>1)%mod+1)*((tr[i].n-tmp+mod)%mod)%mod)%mod;
printf("%lld\n",ans);
}
}
}
不压行带注释
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=155;
const int mod=998244353;
int ksm(int x,int y){
int ret=1;
while(y){
if(y&1)ret=ret*x%mod;
x=x*x%mod;y>>=1;
}return ret;
}
int m;struct TREE{int n,ta,tb,x,y,s0,s1;}tr[N];
struct DM{
int id,x,y;
DM(){}
DM(int a,int b,int c){id=a;x=b;y=c;}
bool operator < (DM a)const{
if(id!=a.id)return id<a.id;
if(x!=a.x)return x<a.x;
return y<a.y;
}
};
map<DM,int> dm;
int D(int id,int x,int y){
if(id==0||x==y)return 0;
if(x>y)swap(x,y);
if(dm.find(DM(id,x,y))!=dm.end())return dm[DM(id,x,y)];int ret;
if(y<=tr[tr[id].ta].n)ret=D(tr[id].ta,x,y);
else if(x<=tr[tr[id].ta].n&&y>tr[tr[id].ta].n)ret=D(tr[id].ta,x,tr[id].x)+D(tr[id].tb,tr[id].y,y-tr[tr[id].ta].n)+1;
else if(x>tr[tr[id].ta].n)ret=D(tr[id].tb,x-tr[tr[id].ta].n,y-tr[tr[id].ta].n);
return dm[DM(id,x,y)]=ret;
}
struct FM{
int id,s,t,d;
FM(){}
FM(int a,int b,int c,int e){id=a;s=b;t=c;d=e;}
bool operator < (FM a)const{
if(id!=a.id)return id<a.id;
if(s!=a.s)return s<a.s;
if(t!=a.t)return t<a.t;
return d<a.d;
}
};
map<FM,int> fm;
int F(int id,int s,int t,int d){
if(id==0)return 0;
if(fm.find(FM(id,s,t,d))!=fm.end())return fm[FM(id,s,t,d)];
int ret,u=tr[id].x,v=tr[id].y+tr[tr[id].ta].n,ta=tr[id].ta,tb=tr[id].tb;
// cerr<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<"FK"<<endl;
if(D(id,s,u)<D(id,s,v)){
// cerr<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<u<<" "<<v<<endl;
int dst=D(id,s,t),dsu=D(id,s,u),dtu=D(id,t,u);
// cerr<<"SB"<<" "<<dst<<" "<<dsu<<" "<<dtu<<endl;
// cerr<<id<<" "<<dsu<<" "<<dst<<" "<<dtu<<endl;
if(dst+dtu==dsu&&t<=tr[ta].n){
ret=(F(ta,s,t,d)+((dsu+1-d)%mod)*(tr[tb].n%mod)%mod+F(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
}
else if(dsu+dst==dtu&&t<=tr[ta].n&&d){
// cerr<<"SB"<<endl;
// cerr<<id<<endl;
ret=F(ta,s,t,d);
}
else if(dsu+dtu==dst&&t>tr[ta].n){
// cerr<<"SB"<<" "<<d<<" "<<dsu<<" OK ";
if(d<=dsu){
// cerr<<"ZZ"<<" ";
ret=(F(ta,s,u,d)+((dsu+1-d)%mod)*(tr[tb].n%mod)%mod+F(tb,v-tr[ta].n,t-tr[ta].n,0))%mod;
}
else {
ret=F(tb,v-tr[ta].n,t-tr[ta].n,d-dsu-1);
}
}
else if(t<=tr[ta].n){
int al=(dsu+dst+dtu)/2;
if(d+dtu<=al){
ret=(F(ta,s,t,d)+((dsu+1-d)%mod)*(tr[tb].n%mod)%mod+F(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
}
else {
ret=F(ta,s,t,d);
}
}
}
else {
// cerr<<"SB"<<" "<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<u<<" "<<v<<endl;
int dst=D(id,s,t),dsv=D(id,s,v),dtv=D(id,t,v);
if(dst+dtv==dsv&&t>tr[ta].n){
// cerr<<"ZZ"<<endl;
ret=(F(tb,s-tr[ta].n,t-tr[ta].n,d)+((dsv+1-d)%mod)*(tr[ta].n%mod)%mod+F(ta,u,u,0))%mod;
}
else if(dsv+dst==dtv&&t>tr[ta].n&&d){
ret=F(tb,s-tr[ta].n,t-tr[ta].n,d);
}
else if(dsv+dtv==dst&&t<=tr[ta].n){
// cerr<<"zz "<<" "<<d<<" "<<dsv<<endl;
if(d<=dsv){
ret=(F(tb,s-tr[ta].n,v-tr[ta].n,d)+((dsv+1-d)%mod)*(tr[ta].n%mod)%mod+F(ta,u,t,0))%mod;
}
else {
ret=F(ta,u,t,d-dsv-1);
}
}
else if(t>tr[ta].n){
int al=(dsv+dst+dtv)/2;
if(d+dtv<=al){
ret=(F(tb,s-tr[ta].n,t-tr[ta].n,d)+((dsv+1-d)%mod)*(tr[ta].n%mod)%mod+F(ta,u,u,0))%mod;
}
else {
ret=F(tb,s-tr[ta].n,t-tr[ta].n,d);
}
}
}
// cerr<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<ret<<endl;
return fm[FM(id,s,t,d)]=ret%mod;
}
struct GM{
int id,s,t,d;
GM(){}
GM(int a,int b,int c,int e){id=a;s=b;t=c;d=e;}
bool operator < (GM a)const{
if(id!=a.id)return id<a.id;
if(s!=a.s)return s<a.s;
if(t!=a.t)return t<a.t;
return d<a.d;
}
};
map<GM,int> gm;
int G(int id,int s,int t,int d){
if(id==0)return 1;
if(gm.find(GM(id,s,t,d))!=gm.end())return gm[GM(id,s,t,d)];
int ret,u=tr[id].x,v=tr[id].y+tr[tr[id].ta].n,ta=tr[id].ta,tb=tr[id].tb;
// cerr<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<"FK"<<endl;
if(D(id,s,u)<D(id,s,v)){
// cerr<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<u<<" "<<v<<endl;
int dst=D(id,s,t),dsu=D(id,s,u),dtu=D(id,t,u);
// cerr<<"SB"<<" "<<dst<<" "<<dsu<<" "<<dtu<<endl;
// cerr<<id<<" "<<dsu<<" "<<dst<<" "<<dtu<<endl;
if(dst+dtu==dsu&&t<=tr[ta].n){
ret=(G(ta,s,t,d)+G(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
}
else if(dsu+dst==dtu&&t<=tr[ta].n&&d){
// cerr<<"SB"<<endl;
// cerr<<id<<endl;
ret=G(ta,s,t,d);
}
else if(dsu+dtu==dst&&t>tr[ta].n){
// cerr<<"SB"<<" "<<d<<" "<<dsu<<" OK ";
if(d<=dsu){
// cerr<<"ZZ"<<" ";
ret=(G(ta,s,u,d)+G(tb,v-tr[ta].n,t-tr[ta].n,0))%mod;
}
else {
ret=G(tb,v-tr[ta].n,t-tr[ta].n,d-dsu-1);
}
}
else if(t<=tr[ta].n){
int al=(dsu+dst+dtu)/2;
if(d+dtu<=al){
ret=(G(ta,s,t,d)+G(tb,v-tr[ta].n,v-tr[ta].n,0))%mod;
}
else {
ret=G(ta,s,t,d);
}
}
}
else {
// cerr<<"SB"<<" "<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<u<<" "<<v<<endl;
int dst=D(id,s,t),dsv=D(id,s,v),dtv=D(id,t,v);
if(dst+dtv==dsv&&t>tr[ta].n){
// cerr<<"ZZ"<<endl;
ret=(G(tb,s-tr[ta].n,t-tr[ta].n,d)+G(ta,u,u,0))%mod;
}
else if(dsv+dst==dtv&&t>tr[ta].n&&d){
ret=G(tb,s-tr[ta].n,t-tr[ta].n,d);
}
else if(dsv+dtv==dst&&t<=tr[ta].n){
// cerr<<"zz "<<" "<<d<<" "<<dsv<<endl;
if(d<=dsv){
ret=(G(tb,s-tr[ta].n,v-tr[ta].n,d)+G(ta,u,t,0))%mod;
}
else {
ret=G(ta,u,t,d-dsv-1);
}
}
else if(t>tr[ta].n){
int al=(dsv+dst+dtv)/2;
if(d+dtv<=al){
ret=(G(tb,s-tr[ta].n,t-tr[ta].n,d)+G(ta,u,u,0))%mod;
}
else {
ret=G(tb,s-tr[ta].n,t-tr[ta].n,d);
}
}
}
// cerr<<id<<" "<<s<<" "<<t<<" "<<d<<" "<<ret<<endl;
return gm[GM(id,s,t,d)]=ret%mod;
}
signed main(){
freopen("link.in","r",stdin);
freopen("link.out","w",stdout);
m=read();tr[0].n=1;tr[0].s0=tr[0].s1=1;
fo(i,1,m){
tr[i].ta=read();tr[i].tb=read();
tr[i].x=read();tr[i].y=read();
tr[i].n=tr[tr[i].ta].n+tr[tr[i].tb].n;
int ns0,ns1,zj=0,now;
now=D(i,tr[tr[i].ta].s0,tr[tr[i].ta].s1);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s0,ns1=tr[tr[i].ta].s1;
now=D(i,tr[tr[i].tb].s0+tr[tr[i].ta].n,tr[tr[i].tb].s1+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].tb].s0+tr[tr[i].ta].n,ns1=tr[tr[i].tb].s1+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s0,tr[tr[i].tb].s0+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s0,ns1=tr[tr[i].tb].s0+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s0,tr[tr[i].tb].s1+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s0,ns1=tr[tr[i].tb].s1+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s1,tr[tr[i].tb].s0+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s1,ns1=tr[tr[i].tb].s0+tr[tr[i].ta].n;
now=D(i,tr[tr[i].ta].s1,tr[tr[i].tb].s1+tr[tr[i].ta].n);
if(now>zj)zj=now,ns0=tr[tr[i].ta].s1,ns1=tr[tr[i].tb].s1+tr[tr[i].ta].n;
tr[i].s0=ns0;tr[i].s1=ns1;int ans=0;
// cerr<<"zj "<<zj<<" "<<ns0<<" "<<ns1<<endl;
// cerr<<"--------------------------------"<<" "<<i<<endl;
if(zj&1){
// cerr<<F(i,ns0,ns1,zj+1>>1)<<" "<<F(i,ns1,ns0,zj+1>>1)<<endl;
ans=(F(i,ns0,ns1,zj+1>>1)+F(i,ns1,ns0,zj+1>>1)+(tr[i].n%mod)*((zj+1>>1)%mod)%mod)%mod;
printf("%lld\n",ans);
}
else {
int tmp=G(i,ns0,ns1,zj>>1)%mod;
ans=(F(i,ns0,ns1,zj>>1)+tmp*((zj>>1)%mod))%mod;
ans=(ans+F(i,ns1,ns0,(zj>>1)+1)+((zj>>1)%mod+1)*((tr[i].n-tmp+mod)%mod)%mod)%mod;
printf("%lld\n",ans);
}
}
}
QQ:2953174821