题意

现在cf上看题意真nm麻烦,有道网页翻译和谷歌翻译鬼畜的一匹

两个人在玩一个游戏。

有一个有\(n\)个数序列\(B\),一开始有一个棋子在\(B\)的第一个位置。

双方轮流操作,第一次操作前将\(B_1-1\)。

然后每次操作,你可以把棋子移到一个位置\(j\in[i,min(i+m,n)]\)且\(B_j>0\),然后将\(B_j-1\),假设双方都采用最优策略,谁先不能操作谁输。

然后你的将要解决的问题是:

给出一个长度为\(n\)的序列\(A\)和\(m\),以及询问数\(q\)。

询问有两种,一种是区间加,另一种是询问\(A\)序列的一个区间,以这段区间作为序列\(B\)进行上面的游戏,问先手还是后手赢。

\(n.q<=2*10^5 m<=5\)

Solution

先考虑给出一个序列\(B\),怎么判断是先手赢还是后手赢。

设\(f_i\)为当一个玩家第一次选到第\(i\)个位置时他会不会赢。

如果\([i+1,i+m]\)里有一个先手必胜,那么这个位置就是先手必败,\(f_i=0\)。

否则就要看当前位置上的值的奇偶性了,冷静分析下不难想到这时当\(A_i\)为偶数时\(f_i=0\),为奇数时\(f_i=1\)。

所以当前\(f_i\)的值我们可以从\(f_j (j \in [i+1,i+m])\)中推出。

然后考虑这东西怎么维护。

发现\(m\)很小,所以我们大力把后\(m\)个\(f_j\)压起来。

用线段树来维护这个东西,每个节点维护当这个区间的右端点右边的\(m\)个位置的\(f_j\)压起来为\(k\)时,这个区间左端点右边的\(m\)个\(f_j\)压起来的值。

合并的时候\(xjb\)的转移下就行了。

修改的话,不难发现当\(d\)为偶数并没有什么用。

我们可以把当区间所有数^1的值也算出来,那么修改就只要\(swap\)一下就行了。

感觉\(NOIP\)后搞文化课导致降智严重啊...连这样的题都要看题解了...\(QAQ\)

#include<bits/stdc++.h>
#define For(i,x,y) for (register int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
#define cross(i,k) for (register int i=first[k];i;i=last[i])
using namespace std;
typedef long long ll;
inline ll read(){
ll x=0;int ch=getchar(),f=1;
while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
if (ch=='-'){f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int N = 3e5+10;
int n,m,q,p,a[N];
struct node{
int f[32];
inline node operator + (const node &b)const{
node ans;
For(i,0,p) ans.f[i]=f[b.f[i]];
return ans;
}
};
inline node New(int x){
node ans;ans.f[0]=x;
For(i,1,p) ans.f[i]=i<<1&p;
return ans;
}
struct SegMent_Tree{
node v[N<<2][2];
bool lazy[N<<2];
inline void push_up(int u){For(i,0,1) v[u][i]=v[u<<1][i]+v[u<<1^1][i];}
inline void Build(int u,int l,int r){
if (l==r){v[u][0]=New(a[l]),v[u][1]=New(a[l]^1);return;}
int mid=l+r>>1;Build(u<<1,l,mid),Build(u<<1^1,mid+1,r);
push_up(u);
}
inline void push_down(int u){
if (!lazy[u]) return;
swap(v[u<<1][0],v[u<<1][1]),swap(v[u<<1^1][0],v[u<<1^1][1]);
lazy[u<<1]^=1,lazy[u<<1^1]^=1,lazy[u]=0;
}
inline void update(int u,int l,int r,int ql,int qr){
if (l>=ql&&r<=qr){lazy[u]^=1,swap(v[u][0],v[u][1]);return;}
int mid=l+r>>1;push_down(u);
if (qr<=mid) update(u<<1,l,mid,ql,qr);
else if (ql>mid) update(u<<1^1,mid+1,r,ql,qr);
else update(u<<1,l,mid,ql,qr),update(u<<1^1,mid+1,r,ql,qr);
push_up(u);
}
inline node Query(int u,int l,int r,int ql,int qr){
if (l>=ql&&r<=qr) return v[u][0];
int mid=l+r>>1;push_down(u);
if (qr<=mid) return Query(u<<1,l,mid,ql,qr);
else if (ql>mid) return Query(u<<1^1,mid+1,r,ql,qr);
else return Query(u<<1,l,mid,ql,qr)+Query(u<<1^1,mid+1,r,ql,qr);
}
}t;
int main(){
n=read(),m=read(),q=read(),p=(1<<m)-1;
For(i,1,n) a[i]=read()&1;
t.Build(1,1,n);
while (q--){
int opt=read(),l=read(),r=read();
if (opt==2) puts(t.Query(1,1,n,l,r).f[0]&1?"2":"1");
else if (read()&1) t.update(1,1,n,l,r);
}
}

Codedforces 1076G Array Game 线段树的更多相关文章

  1. codeforces 482B. Interesting Array【线段树区间更新】

    题目:codeforces 482B. Interesting Array 题意:给你一个值n和m中操作,每种操作就是三个数 l ,r,val. 就是区间l---r上的与的值为val,最后问你原来的数 ...

  2. Light OJ-1082 - Array Queries,线段树区间查询最大值,哈哈,水过~~

                                                                                                        ...

  3. Codeforces E. Interesting Array(线段树)

    题目描述: D. Interesting Arraytime limit per test1 secondmemory limit per test256 megabytesinputstandard ...

  4. B. Interesting Array(线段树)

    B. Interesting Array time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. CodeForces Round #179 (295A) - Greg and Array 一个线段树做两次用

    线段树的区间更新与区间求和...一颗这样的线段树用两次... 先扫描1~k...用线段树统计出每个操作执行的次数... 那么每个操作就变成了 op. l  , op.r , op.c= times* ...

  6. CF1114F Please, another Queries on Array?(线段树,数论,欧拉函数,状态压缩)

    这题我在考场上也是想出了正解的……但是没调出来. 题目链接:CF原网 题目大意:给一个长度为 $n$ 的序列 $a$,$q$ 个操作:区间乘 $x$,求区间乘积的欧拉函数模 $10^9+7$ 的值. ...

  7. CF 1023D Array Restoration - 线段树

    题解 非常容易想到的线段树, 还可以用并查集来. 还有一位大神用了$O(n)$ 就过了Orz 要判断是否能染色出输入给出的序列,必须满足两个条件: 1. 序列中必须存在一个$q$ 2. 两个相同的数$ ...

  8. CodeForces 266E More Queries to Array...(线段树+式子展开)

    开始觉得是规律题的,自以为是的推了一个规律,结果测试数据都没过....看了love神的博客才发现只是把式子展开就找到规律了.不过挺6的是我虽然想错了,但是维护的的东西没有错,只是改改(改了进两个小时好 ...

  9. Codeforces #504(div1+div2) 1023D Array Restoration(线段树)

    题目大意:给你一个数组,数组是经过q次区间覆盖后的结果,第i次覆盖是把区间内的值赋值为i,其中有若干个地方数值未知(就是0),让你判断这个数组是否可以经过覆盖后得到的,如果可以,输出任意一种可行数组. ...

随机推荐

  1. 引发类型为“System.OutOfMemoryException”的异常

    在运维工作中,经常能接到客户的反馈这个:引发类型为“System.OutOfMemoryException”的异常.客户反馈物理内存都还有富余,怎么报内存不足的错误呢! 什么时候会引发System.O ...

  2. 简析CSRF

    1.简介 CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF ...

  3. python的新特性

    http://www.jb51.net/article/67699.htm Python中用format函数格式化字符串的用法:http://www.jb51.net/article/63672.ht ...

  4. KVM,QEMU,libvirt入门学习笔记【转】

    转自:http://blog.csdn.net/julykobe/article/details/27571387 注:本文内容均来自网络,我只是在此做了一些摘抄和整理的工作,来源均有注明. 0.虚拟 ...

  5. C#中HttpWebRequest的GetRequestStream执行的效率太低,甚至偶尔死掉

    为了提高httpwebrequest的执行效率,查到了一些如下设置 request.ServicePoint.Expect100Continue = false; request.ServicePoi ...

  6. Django集成Xadmin list index out of range报错解决方案

    return self.render(context) File "C:\Python36\lib\site-packages\django\template\defaulttags.py& ...

  7. Django 基于类的视图(CBV)执行流程 CBV 源码分析

    一.CBV(基于类的视图) 视图是可以调用的,它接受请求并返回响应,这不仅仅是一个函数,Django提供了一些可以用作视图的类的例子,这些允许您通过继承或mixin来构建视图并重用代码. 基本示例 D ...

  8. jQuery基本筛选器-表单筛选器-关系筛选器

    一.基本筛选器 :first // 第一个 :last // 最后一个 :eq(index)// 索引等于index的那个元素 :even // 匹配所有索引值为偶数的元素,从 0 开始计数 :odd ...

  9. jQuery简单介绍

    一.jQuery介绍 jQuery是一个轻量级的.兼容多浏览器的JavaScript库. jQuery使用户能够更方便地处理HTML Document.Events.实现动画效果.方便地进行Ajax交 ...

  10. 数据库--mysql介绍

    一:什么是数据库 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. 我们也可以将数据存储在文件 ...