纪念灾难
一些时候,我们需要更细致一些。
在我们把答案式子成功推出,并且注意到了所有的统计答案细节之后。
遇到在小样例上全过,但是大样例GG的情况时,要注意一些预处理的量是否正确。
比如一些次幂项,是否会有部分调用越界,否则容易浪费时间。
这道题。
答案稍微想一想就可以转化,然后开始想式子。
初始三个统计式子(枚举2进制第k位,all是子树大小,cnt是该位上有几个点为1):
ps:cnt在非根处统计父节点,根处不统计。
\[2^k×2^{n-all+1}×(\sum_{i=2}^{cnt}\binom{cnt}{i}[i\%2=1]×2^{all-cnt}+cnt×(2^{all-cnt}-1))(u!=1)
\]
\[2^k×2^{n-all}×(\sum_{i=1}^{cnt}\binom{cnt}{i}[i\%2=0]×2^{all-cnt-1}+2^{all-cnt-1}-1)(u=1,f[k]=1)
\]
\[2^k×2^{n-all}×2^{all-cnt-1}×(\sum_{i=1}^{cnt}\binom{cnt}{i}[i\%2=1])(u=1,f[k]=0)
\]
化简后贡献为三个式子:
\[2^{n+k-2}-cnt×2^{n+k-all-1}(u!=1)
\]
\[2^{n+k-all}×(2^{all-2}-1)(u=1,f[k]=1)
\]
\[2^{n+k-2}(u=1,f[k]=0)
\]
考试结束,没事,接着打。
打出来交上去,全WA,于是狂调不止。
注意到第二种情况对应代码里面我们少减了1。
打出来交上去,全WA,于是狂调不止。
然后我们成功的发现了一处问题,第二个式子,由于我们是根据二项式定理得来的,发现在cnt=0时它有问题。
所以在cnt=0时变为:
\[2^{n+i-all}×(2^{all-1}-1)(u=1,f[i]=1)
\]
打出来交上去,全WA,于是狂调不止。
经过两个小时的折磨,我们成功精神崩溃,然后去找同志们核对式子。
核对了一圈发现自己完全正确,于是回来狂调不止,最后在对拍下发现奇妙现象,在值域小于等于4时全部正确。
这时才发现,我们前面合并了多个2的次幂,最终式子承受不了只在2的n次之内的预处理。
打出来交上去,AC。
...再细致点吧。
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
#define qr qr()
#define ps push_back
#define pa pair<int,int>
#define ve vector
#define fi first
#define se second
using namespace std;
const int N=1e5+400,mod=1e9+7;
const ll INF=0x7fffffffffffffff;
int n,tot,h[N],a[N],cnt[N][31],all[N];
ll ans,p[N*2];
inline int qr{
int x=0;char ch=getchar();
while(ch>57||ch<48)ch=getchar();
while(ch>=48&&ch<=57)x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x;
}
struct node{
int t,nx;
}e[N];
inline void add(int f,int t){
e[++tot]={t,h[f]};h[f]=tot;
}
bool f[32];
void dfs(int u){
all[u]=1;
if(u!=1){
for(int i=0;i<=30;++i){
if((a[u]>>i)&1)++cnt[u][i];
}
}else for(int i=0;i<=30;++i)if((a[u]>>i)&1)f[i]=1;
for(int i=h[u];i;i=e[i].nx){
int v=e[i].t;
dfs(v);
for(int i=0;i<=30;++i){
if((a[v]>>i)&1)++cnt[u][i];
}++all[u];
}
if(!all[u])return;
if(u!=1){
for(int i=0;i<=30;++i){
int k=cnt[u][i];
if(!k)continue;
ans=(ans+p[n+i-2])%mod;
ans=(ans-k*p[n+i-all[u]-1]%mod+mod)%mod;
// ans=(ans+p[n+i-k-2]*((p[k]-2*k+mod)%mod)%mod)%mod;
// ans=(ans+p[n+i-all[u]-1]*k%mod*(p[all[u]-k]-1))%mod;
}
}
else{
for(int i=0;i<=30;++i){
int k=cnt[u][i];
if(!k&&!f[i])continue;
// cout<<all[u]<<' '<<cnt[u][i]<<' '<<f[i]<<' '<<i<<endl;
if(f[i]&&cnt[u][i]>0)ans=(ans+p[n+i-all[u]]*(p[all[u]-2]-1))%mod;
else if(f[i])ans=(ans+p[n+i-all[u]]*(p[all[u]-1]-1))%mod;
else ans=(ans+p[n+i-2])%mod;
}
}
}
void init(){
n=qr;
p[0]=1;
for(int i=1;i<=N;++i)p[i]=p[i-1]*2%mod;
for(int i=1;i<=n;++i)a[i]=qr;
for(int i=1,f;i<n;++i)f=qr,add(f,i+1);
dfs(1);cout<<ans;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
freopen("climb.in","r",stdin);freopen("climb.out","w",stdout);
init();
return 0;
}
https://www.cnblogs.com/shining-like-stars

浙公网安备 33010602011771号