当前位置: 首页 > news >正文

CF2032F Peanuts - Link

首先给个结论:反 nim 游戏(谁取到最后一个谁输)的游戏先手的必胜条件:

  1. 当所有数都是 \(1\) 时,数的个数为奇先手必败,否则必胜。
  2. 其他情况,所有数异或和为 \(0\) 先手必败,否则必胜。
    \(f_{i,0/1}\) 表示前 \(i\) 个,先手取到 / 没取到最后一个的方案数。
    考虑转移。
    枚举 \(j\) 表示上一个块的结尾。
\(f_{i,0}\) 的转移

如果 \(i\)\(j\)nim 游戏先手必胜,那  Alice 就要当这一块的先手,也就是前一块没取到最后一个,\(f_{i,0}+=f_{j,1}\)
如果 \(i\)\(j\)nim 游戏先手必败,那  Alice 就要当这一块的后手,也就是前一块取到最后一个,\(f_{i,0}+=f_{j,0}\)

\(f_{i,1}\) 的转移

如果 \(i\)\(j\) 玩反 nim 游戏先手必胜,那  Alice 就要当这一块的先手,也就是前一块没取到最后一个,\(f_{i,1}+=f_{j,1}\)
如果 \(i\)\(j\) 玩反 nim 游戏先手必败,那  Alice 就要当这一块的后手,也就是前一块取到最后一个,\(f_{i,1}+=f_{j,0}\)
这样,就得到了 \(\mathcal{O}(n^2)\) 的做法。

\(\mathcal{O}(n^2)\) 代码

#include<bits/stdc++.h>
using namespace std;
namespace IO{template<typename T>inline void read(T&x){x=0;char c=getchar();bool f=0;while(!isdigit(c)) c=='-'?f=1:0,c=getchar();while(isdigit(c)) x=x*10+c-'0',c=getchar();f?x=-x:0;}template<typename T>inline void write(T x){if(x==0){putchar('0');return ;}x<0?x=-x,putchar('-'):0;short st[50],top=0;while(x) st[++top]=x%10,x/=10;while(top) putchar(st[top--]+'0');}inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}inline void write(char c){putchar(c);}inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
const int maxn=1000010,mod=998244353;
int n,a[maxn],f[maxn][2];
void solve(){read(n);for(int i=1;i<=n;i++) read(a[i]),a[i]^=a[i-1],f[i][0]=f[i][1]=0;f[0][1]=1;for(int i=1;i<=n;i++){for(int j=0;j<i;j++){if(a[i]^a[j]) f[i][0]=(f[i][0]+f[j][1])%mod;else f[i][0]=(f[i][0]+f[j][0])%mod;}bool ff=1;for(int j=i;j>=1;j--){if((a[j]^a[j-1])!=1) ff=0;if(ff){if(i-j+1&1) f[i][1]=(f[i][1]+f[j-1][0])%mod; else f[i][1]=(f[i][1]+f[j-1][1])%mod;}else{if(a[i]^a[j-1]) f[i][1]=(f[i][1]+f[j-1][1])%mod;else f[i][1]=(f[i][1]+f[j-1][0])%mod;}}}write(f[n][0]);
}
signed main(){int T;read(T);while(T--) solve(),write("\n");return 0;
}

但是这样会 \(TLE\)。考虑优化。
对于 \(f_{i,0}\) 的转移,用一个桶维护一下即可。
对于 \(f_{i,1}\) 的转移,用一个桶维护前面的信息,末尾连续的 \(1\) 另开一个数组存。

代码

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/exception.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/list_update_policy.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/trie_policy.hpp>
using namespace std;
namespace IO{template<typename T>inline void read(T&x){x=0;char c=getchar();bool f=0;while(!isdigit(c)) c=='-'?f=1:0,c=getchar();while(isdigit(c)) x=x*10+c-'0',c=getchar();f?x=-x:0;}template<typename T>inline void write(T x){if(x==0){putchar('0');return ;}x<0?x=-x,putchar('-'):0;short st[50],top=0;while(x) st[++top]=x%10,x/=10;while(top) putchar(st[top--]+'0');}inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}inline void write(char c){putchar(c);}inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
#define int long long
const int maxn=1000010,mod=998244353;
int n,a[maxn],f[maxn][2],h,hh,w[2][2];
__gnu_pbds::gp_hash_table<int,int>mp[2],mp2[2];
void solve(){mp[0].clear(),mp[1].clear();mp2[0].clear(),mp2[1].clear();read(n);for(int i=1;i<=n;i++) read(a[i]),a[i]^=a[i-1],f[i][0]=f[i][1]=0;f[0][1]=1;mp[1][a[0]]=1;h=1;hh=0;w[0][0]=w[1][0]=w[1][1]=0;w[0][1]=1;int wz=0;for(int i=1;i<=n;i++){f[i][0]=(h-mp[1][a[i]]+mp[0][a[i]]+mod)%mod;if((a[i]^a[i-1])>1){while(wz<i){(mp2[0][a[wz]]+=f[wz][0])%=mod;(mp2[1][a[wz]]+=f[wz][1])%=mod;(hh+=f[wz][1])%=mod;wz++;}w[0][0]=w[0][1]=w[1][0]=w[1][1]=0;}f[i][1]=(hh-mp2[1][a[i]]+mp2[0][a[i]]+mod)%mod;f[i][1]=(f[i][1]+w[!(i&1)][0]+w[i&1][1])%mod;(mp[0][a[i]]+=f[i][0])%=mod;(mp[1][a[i]]+=f[i][1])%=mod;(h+=f[i][1])%mod;(w[i&1][0]+=f[i][0])%=mod;(w[i&1][1]+=f[i][1])%=mod;}write(f[n][0]);
}
signed main(){int T;read(T);while(T--) solve(),write("\n");return 0;
}
http://www.jsqmd.com/news/183531/

相关文章:

  • 适用于多场景的开源文本转语音模型推荐列表
  • 如何将Sonic集成进现有AIGC工作流?以ComfyUI为例说明
  • Sonic模型开源吗?在哪里可以获取其HuggingFace镜像地址
  • CF2032虚拟赛总结 - Link
  • 变形金刚汽车人语音:擎天柱说出中文版经典台词
  • VoxCPM-1.5-TTS-WEB-UI推理性能优化:减少延迟提升响应速度
  • 支持高音质输出的中文TTS模型VoxCPM-1.5使用指南
  • 土库曼斯坦地毯工艺:匠人讲述编织背后的故事
  • Sonic生成时间统计:不同硬件配置下的性能基准测试
  • Git commit cherry-pick精选VoxCPM-1.5-TTS关键补丁移植
  • 一张静态图+一段音频动态说话人?Sonic模型带你实现
  • UltraISO注册码最新版哪里找?先了解VoxCPM-1.5-TTS-WEB-UI语音功能亮点
  • pytest + pytest-mock + pytest-parametrize为基础构建测试框架
  • Sonic生成视频用于商业广告需要授权吗?法律风险提示
  • 量化校准集动态调整实战
  • 使用Typora编写Sonic项目文档?Markdown编辑器推荐搭配
  • 工信部将Sonic纳入新一代人工智能创新项目库
  • Git tag标记VoxCPM-1.5-TTS-WEB-UI重要发布版本
  • Ehercat代码解析中文摘录<3>
  • Sonic数字人英文语音生成效果测试:发音准确度达行业前列
  • 小红书博主分享Sonic生成数字人种草视频
  • 超高品质数字人视频生成工作流使用Sonic全攻略
  • 《创业之路》-796-软件系统的兼容性、适应性、适配性与人际交往中的兼容性、适应性、适配性
  • 福建土楼围屋:客家人大年初一的祭祖祷告
  • 武侠小说江湖语录:金庸笔下人物开口说话了
  • P1861 星之器
  • 《创业之路》-797-企业管理中,追求高效和专业性是执行层中基层管理评判的标准;方向和立场的正确性和利益的价值性是高层管理者评判的标准。中基层与高层本就不在一个频道上。
  • [CCO 2022] Double Attendance
  • 曾贝贝湖南卫视跨年首秀搭档徐佳莹 《身骑白马》融合舒曼金曲惊艳全场
  • 意大利歌剧选段:AI演唱《图兰朵》茉莉花片段