- 单向边森林不能通过dfs找环
- 抽象的题目需要通过模拟样例理解题意
- 列表模拟样例
- 链式前向星双倍空间(边&边的访问函数)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int mod=1000000007;
long long a[500005],b[500005],w[500005],c[500005],p[500005],cnt[500005];
long long h[500005],ne[1000005],t[1000005],tot,m,n;
bool v[500005],f[1000005];
long long jc[500005],jcinv[500005];
vector<long long>g[500005];
long long read1()
{
char cc=getchar();
while(!(cc>=48&&cc<=57))
{
if(cc=='-')
{
break;
}
cc=getchar();
}
bool f=false;
long long s=0;
if(cc=='-')
{
f=true;
}
else
{
s=cc-48;
}
while(1)
{
cc=getchar();
if(cc>=48&&cc<=57)
{
s=s*10+cc-48;
}
else
{
break;
}
}
if(f==true)
{
s=-s;
}
return s;
}
long long power(long long n,long long p)
{
if(p==0)
{
return 1;
}
else if(p==1)
{
return n%mod;
}
else if(p%2==0)
{
long long tmp=power(n,p/2);
return tmp*tmp%mod;
}
else
{
long long tmp=power(n,p/2);
return tmp*tmp%mod*n%mod;
}
}
void add(long long u,long long v)
{
tot++;
ne[tot]=h[u];
h[u]=tot;
t[tot]=v;
}
long long dfs1(long long n1)
{
v[n1]=true;
bool pd=false;
for(long long i=h[n1];i;i=ne[i])
{
if(f[i]==false)
{
f[i]=true;
if(i>n)
{
f[i-n]=true;
}
else
{
f[i+n]=true;
}
long long w=t[i];
if(v[w]==false)
{
long long tmp=dfs1(w);
if(tmp>0)
{
pd=true;
}
}
else
{
m++;
c[w]=m;
g[m].push_back(w);
pd=true;
}
}
}
if(pd==true)
{
if(c[n1]==0)
{
g[m].push_back(n1);
return c[n1]=m;
}
else
{
return 0;
}
}
return 0;
}
void dfs2(long long n1)
{
v[n1]=true;
for(long long i=h[n1];i;i=ne[i])
{
long long w=t[i];
if(i<=n&&v[w]==false)
{
if(p[w]==-1)
{
if(p[n1]==0)
{
p[w]=0;
cnt[w]=0;
}
else
{
cnt[w]=cnt[n1]+1;
p[w]=jcinv[cnt[w]];
}
}
dfs2(w);
}
}
}
void pre()
{
jc[0]=1;
jcinv[0]=1;
for(long long i=1;i<=500000;i++)
{
jc[i]=jc[i-1]*i%mod;
}
jcinv[500000]=power(jc[500000],1000000005);
for(long long i=500000;i>1;i--)
{
jcinv[i-1]=jcinv[i]*i%mod;
}
}
int main()
{
// freopen("H.in","r",stdin);
// freopen("H.out","w",stdout);
pre();
long long T;
cin>>T;
while(T--)
{
n=read1();
for(long long i=1;i<=n;i++)
{
a[i]=read1();
p[i]=-1;
cnt[i]=0;
}
for(long long i=1;i<=n;i++)
{
b[i]=read1();
add(b[i],i);
}
for(long long i=1;i<=n;i++)
{
add(i,b[i]);
}
for(long long i=1;i<=n;i++)
{
w[i]=read1();
}
for(long long i=1;i<=n;i++)
{
if(a[i]<a[b[i]])
{
p[i]=1;
cnt[i]=1;
}
else if(a[i]>=a[b[i]]+w[b[i]])
{
p[i]=0;
cnt[i]=0;
}
}
for(long long i=1;i<=n;i++)
{
if(!v[i])
{
long long tmp=dfs1(i);
}
}
for(long long i=1;i<=n;i++)
{
v[i]=false;
}
for(long long i=1;i<=m;i++)
{
long long x=-1;
for(long long j=0;j<g[i].size();j++)
{
if(p[g[i][j]]!=-1)
{
x=g[i][j];
}
}
if(x==-1)
{
for(long long j=0;j<g[i].size();j++)
{
p[g[i][j]]=0;
cnt[g[i][j]]=0;
}
x=g[i][0];
}
dfs2(x);
}
for(long long i=1;i<n;i++)
{
printf("%lld ",(a[i]+p[i]*w[i]%mod)%mod);
}
printf("%lld\n",(a[n]+p[n]*w[n]%mod)%mod);
for(long long i=1;i<=tot;i++)
{
f[i]=false;
}
tot=0;
for(long long i=1;i<=n;i++)
{
v[i]=false;
h[i]=0;
c[i]=0;
}
for(long long i=1;i<=m;i++)
{
g[i].clear();
}
m=0;
}
return 0;
}