纪念灾难
一些时候,我们需要更细致一些。
在我们把答案式子成功推出,并且注意到了所有的统计答案细节之后。
遇到在小样例上全过,但是大样例GG的情况时,要注意一些预处理的量是否正确。
比如一些次幂项,是否会有部分调用越界,否则容易浪费时间。
这道题。
答案稍微想一想就可以转化,然后开始想式子。
初始三个统计式子(枚举2进制第k位,all是子树大小,cnt是该位上有几个点为1):
ps:cnt在非根处统计父节点,根处不统计。
化简后贡献为三个式子:
考试结束,没事,接着打。
打出来交上去,全WA,于是狂调不止。
注意到第二种情况对应代码里面我们少减了1。
打出来交上去,全WA,于是狂调不止。
然后我们成功的发现了一处问题,第二个式子,由于我们是根据二项式定理得来的,发现在cnt=0时它有问题。
所以在cnt=0时变为:
打出来交上去,全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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现