P9580 「Cfz Round 1」Wqs Game 题解
挺好的博弈论题,这是一个跟官方题解不太一样的做法。
遇到这种组合游戏可以先考虑逆推胜负,把握一下规律,我们先从一个区间的胜负判断开始入手。
考察区间中最后一个数字的从属关系,如果它属于弈,因为 \(a_i>0\),如果前面传来的数字非空,则弈不用选择也可以获胜,否则只要选择当前的数即可。
如果它属于博,那么这个数得刚好为 0 或者等于 \(a_i\),博才有办法获胜,以此推广到最后有多个数属于博的情况:只有前面传来的数能被这些数异或表示(在它们的张成空间中),博才能获胜。
而这个规律推广到更前面的连续段也是适用的,即对于数列的任意一个前缀中属于弈的数的张成空间,都是对应后缀属于博的数的张成空间的子集时,博才能获胜。
找到了规律,我们接着来设计算法进行统计,一个维护这种“区间中的子区间”数量的常用方法是对一个端点进行扫描线,维护 \(S\) 数组表示以对应位置为开头或结尾,且以当前扫描到的这个数为另一个端点时,合法的区间数。
由于刚才我们是从右往左推理,我们也动态从右往左扫描,对于一个以弈拥有的数为右端点的区间贡献肯定为 \(r-l+1\),而另一种区间如果在扫描中遇到了一个节点,且它不在当前这个张成空间中,后面无论再怎么扫也一定无解,前面一定有解,也就是说这种胜负具有一定单调性。
这启发我们先预处理出每个弈拥有的点在右端点到哪才能被右边属于博的数异或表示出,记为 \(rpos_i\) 可以倒着扫描整个序列,贪心维护一个线性基,每次加数时淘汰时间比较老的节点,当加到 \(a_{i+1}\) 时就可以处理 \(a_i\) 的信息,对它用到的节点的时间戳取最大即可。
回到刚才的扫描线,由于“当前没有机会的右端点集合”只要一开始把所有都加进去就是只增不减,每次扫描到一个属于弈的数就把 \(i\) 到 \(rpos_i\) 中的所有数标记为合法,可以使用并查集或者 set 维护,之后开个树状数组维护答案,这里数点的方式有很多种,这里不再赘述。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<vector>
#define N 500005
#define M 1500006
#define ll long long
using namespace std;
typedef unsigned long long ul;
typedef unsigned int ui;
ui ans;
ui Ans;
ul Sd,Cnt;
ul cnt,n,q,tp,a[N];
ul Rd(){Sd^=Sd<<19,Sd^=Sd>>12,Sd^=Sd<<29;return Sd^=++Cnt;}
char s[N];
void GetA(ul &a){a=Rd()%((1ll<<60)-2)+1;}
void GetLR(ul &l,ul &r){
l=Rd()%n+1,r=Rd()%n+1;
if(l>r)swap(l,r);
}
ll read(){
ll x=0;char ch=getchar();
while(ch<'0' || ch>'9')ch=getchar();
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x;
}
//-----------------------------------------------
struct que{
ul l,r;
}Q[M];
void init(){
n=read();q=read();tp=read();
char ch=getchar();
while(ch<'0' || ch>'1')ch=getchar();
while(ch>='0' && ch<='1'){s[++cnt]=ch;ch=getchar();}
if(tp){
Sd=tp,Cnt=0;
for(ll i=1;i<=n;++i)GetA(a[i]);
for(ll qi=1;qi<=q;++qi){GetLR(Q[qi].l,Q[qi].r);}
}
else{
for(ll i=1;i<=n;i++)a[i]=read();
for(ll i=1;i<=q;i++){Q[i].l=read();Q[i].r=read();}
}
}
ll rpos[N];
vector<que> P[N];
ll bas[65],ti[65];
void insert(ll x,ll t){
for(ll i=61;i>=0;i--){
if(x&(1ll<<i)){
if(!bas[i]){bas[i]=x;ti[i]=t;return;}
else if(t<ti[i]){swap(x,bas[i]);swap(t,ti[i]);x^=bas[i];}
else x^=bas[i];
}
}
}
ll jud(ll x){
ll ans=0;
for(ll i=61;i>=0;i--){
if(x&(1ll<<i)){
x^=bas[i];ans=max(ans,ti[i]);
}
}
if(x) return n+1;
else return ans;
}
int ask_b(ll x,ll t){
ll ans=0;
for(ll i=61;i>=0;i--){
if(x&(1ll<<i) && t<=ti[i]){
x^=bas[i];ans=max(ans,ti[i]);
}
else if(x&(1ll<<i))return false;
}
}
set<ll> S;
ll F[N],G[N];
ll lowbit(ll x){
return x&(-x);
}
void add(ll x,ll val,ll *K){
while(x<=n){
K[x]+=val;
x+=lowbit(x);
}
}
ll ask(ll x,ll *K){
ll ans=0;
while(x){
ans+=K[x];
x-=lowbit(x);
}
return ans;
}
ui an[N];
int main(){
init();ll pos=1;
rpos[n]=n+1;
for(ll i=n;i>=1;i--){
if(s[i]=='0')insert(a[i],i);
else rpos[i]=jud(a[i]);
}
for(ll i=1;i<=n;i++)if(s[i]=='0'){S.insert(i);add(i,i,F);add(i,1,G);}
for(ll i=1;i<=q;i++)P[Q[i].l].push_back((que){i,Q[i].r});
for(ll i=n;i>=1;i--){
if(s[i]=='1'){
set<ll>::iterator itt=S.lower_bound(i);
set<ll>::iterator it=itt;
for(;itt!=S.end() && *itt<rpos[i];itt++){
add(*itt,-*itt,F);add(*itt,-1,G);
add(*itt,*itt-i,F);
}
S.erase(it,itt);
}
for(ll j=0;j<P[i].size();j++){
ll r=P[i][j].r;
ans=0;ans=ask(r,F)-ask(i-1,F)-(ask(r,G)-ask(i-1,G))*(i-1);
ans=(ll)(r-i+2)*(r-i+1)/2-ans;
if(!tp)an[P[i][j].l]=(ans%(1ll<<32));
ans%=(1ll<<32);
ans=(ans*P[i][j].l)%(1ll<<32);
ui tmp=ans;
Ans^=tmp;
}
}
if(tp)cout<<Ans;
else for(ll i=1;i<=q;i++)cout<<an[i]<<endl;
}
P9580 「Cfz Round 1」Wqs Game 题解的更多相关文章
- LibreOJ #525. 「LibreOJ β Round #4」多项式
二次联通门 : LibreOJ #525. 「LibreOJ β Round #4」多项式 官方题解 : /* LibreOJ #525. 「LibreOJ β Round #4」多项式 由于会有多种 ...
- loj #547. 「LibreOJ β Round #7」匹配字符串
#547. 「LibreOJ β Round #7」匹配字符串 题目描述 对于一个 01 串(即由字符 0 和 1 组成的字符串)sss,我们称 sss 合法,当且仅当串 sss 的任意一个长度为 ...
- [LOJ#531]「LibreOJ β Round #5」游戏
[LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...
- [LOJ#530]「LibreOJ β Round #5」最小倍数
[LOJ#530]「LibreOJ β Round #5」最小倍数 试题描述 第二天,LCR 终于启动了备份存储器,准备上传数据时,却没有找到熟悉的文件资源,取而代之的是而屏幕上显示的一段话: 您的文 ...
- [LOJ#516]「LibreOJ β Round #2」DP 一般看规律
[LOJ#516]「LibreOJ β Round #2」DP 一般看规律 试题描述 给定一个长度为 \(n\) 的序列 \(a\),一共有 \(m\) 个操作. 每次操作的内容为:给定 \(x,y\ ...
- [LOJ#515]「LibreOJ β Round #2」贪心只能过样例
[LOJ#515]「LibreOJ β Round #2」贪心只能过样例 试题描述 一共有 \(n\) 个数,第 \(i\) 个数 \(x_i\) 可以取 \([a_i , b_i]\) 中任意值. ...
- [LOJ#525]「LibreOJ β Round #4」多项式
[LOJ#525]「LibreOJ β Round #4」多项式 试题描述 给定一个正整数 k,你需要寻找一个系数均为 0 到 k−1 之间的非零多项式 f(x),满足对于任意整数 x 均有 f(x) ...
- [LOJ#526]「LibreOJ β Round #4」子集
[LOJ#526]「LibreOJ β Round #4」子集 试题描述 qmqmqm有一个长为 n 的数列 a1,a2,……,an,你需要选择集合{1,2,……,n}的一个子集,使得这个子集中任意两 ...
- [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)
[LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 …… 接着他们发现自己收 ...
- LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力
二次联通门 : LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 /* LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 叫做计算几 ...
随机推荐
- AI 时代的视频云转码移动端化——更快、更好、更低、更广
编者按: AI技术的落地是渐渐地从服务器端.云端落地,逐步到移动端及边缘设备上.这些年随着AI技术的进步,轻量级算法模型开始在移动端实时跑起来,并且移动端算法也在不断进行迭代和完善,而对于实时直播场景 ...
- #Powerbi 10分钟,理解 Rankx 排名函数
一:本文思维导图及示例数据图 1.1思维导图 1.2 示例数据图 二:度量值示例 2.1 函数简介 RANKX 首先为的每一行计值表达式,将结果临时存储为一个值列表.然后在当前筛选上下文中计值,将得 ...
- 2023-07-14:讲一讲Kafka与RocketMQ中存储设计的异同?
2023-07-14:讲一讲Kafka与RocketMQ中存储设计的异同? 答案2023-07-14: 在Kafka中,文件的布局采用了Topic/Partition的方式,每个分区对应一个物理文件夹 ...
- fastposter v2.16.0 让海报开发更简单
fastposter v2.16.0 让海报开发更简单 fastposter海报生成器是一款快速开发海报的工具.只需上传一张背景图,在对应的位置放上组件(文字.图片.二维.头像) 点击代码直接生成各种 ...
- 零基础入门——从零开始学习PHP反序列化笔记(二)
魔术方法 魔术方法介绍 __construct() 触发时机:实例化对象之前 构造函数,在实例化一个对象的时候,首先会去自动执行的一个方法; <?php class User { public ...
- C#程序变量统一管理例子 - 开源研究系列文章
今天讲讲关于C#应用程序中使用到的变量的统一管理的代码例子. 我们知道,在C#里使用变量,除了private私有变量外,程序中使用到的公共变量就需要进行统一的存放和管理.这里笔者使用到的公共变量管理库 ...
- Blazor前后端框架Known-V1.2.14
V1.2.14 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. Gitee: https://gitee.com/known/Known Git ...
- TIKZ全局样式设置
tikz绘图引擎 TIKZ绘图引擎是基于tex实现,代码极其复杂,每次编写都要单独设置样式,甚是繁琐,如何能够全局设置呢? \begin{tikzpicture}[ auto, % 决策结点 deci ...
- 推荐一个react上拉加载更多插件:react-infinite-scroller
在开发网页和移动应用时,经常需要处理大量数据的展示和加载.如果数据量非常大,一次性全部加载可能会导致页面卡顿或崩溃.为了解决这个问题,我们可以使用无限滚动(Infinite Scroll)的技术.Re ...
- ionic4请求skynet服务器的资源跨域问题
最近在做一个后台接口, 顺便用ionic4写了个简单的管理后台, 本来skynet管理后台监听的端口是6666, 但是发现chrome默认对一些接口不友善, 虽然可以通过设置启动参数来解决, 但是还是 ...