选数 题解
选数 题解
首先,设最初取值为
注意到:
那么我们实际上要求的即为:
简单带入一下
有趣的是,
这也可以证明我们对下列所有的
所以式子变为:
将别问90pts是为什么
再者,再看这个式子:
这样的话,式子化为
我们设solve(p,now,ans)
表示当前遍历到trie的指针
此时我们来分类讨论,毕竟先后手都足够聪明。
- 若
有两个儿子,则不论第 位填什么,都有决策使这个位变为0,所以递归solve(t[p][0],now-1,ans<<1),slove(t[p][1],now-1,ans<<1)
- 若
仅有一个儿子,则可以反着填数,使这一位变成1
。设儿子为 ,则递归solve(k,now-1,ans<<1|1)
- 若
没有儿子,直接返回(ans,1)
(最大值和个数)
最后返回值是返回各个分支的最大值,注意个数的统计。
核心代码如下:
#define pr pair<int,int>
#define mk make_pair
pr query(int p,int ans){
if(t[p][0]==0&&t[p][1]==0)return mk(ans,1);
if(t[p][0]&&t[p][1]){
pr ans1=query(t[p][0],ans<<1);
pr ans2=query(t[p][1],ans<<1);
if(ans1.first==ans2.first)return mk(ans1.first,ans1.second+ans2.second);
return max(ans1,ans2);
}
if(t[p][0])return query(t[p][0],ans<<1|1);
return query(t[p][1],ans<<1|1);
}
signed main(){
ios::sync_with_stdio(false);
cin>>n>>m;
n2=1;for(int i=1;i<=n;i++)n2*=2;
for(int i=1;i<=m;i++)cin>>a[i];
for(int i=1;i<=m;i++)pre[i]=pre[i-1]^a[i];
for(int i=1;i<=m;i++)s[i]=get(pre[i])^pre[n]^pre[i];
for(int i=1;i<=m;i++)insert(s[i]);
insert(0);
pr ans=query(1,0);
cout<<ans.first<<endl<<ans.second<<endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!