loj #6138. 「2017 山东三轮集训 Day4」Right
题目:
题解:
暴力一波 \(SG\) 函数可以发现这么一个规律:
- \(p\) 为奇数的时候 : \(SG(n) = n \% 2\)
- \(p\) 为偶数的时候 : \(SG(n) = n \% (p+1) == p ? 2 : n \% (p+1) \% 2\)
对于奇数的情况我们就可以直接用一棵支持区间取反和区间查询 \(1\) 的个数的线段树搞定。
那么难点在于偶数的情况。
我们可以采用分块算法.
每个块分别中保存 \(\bmod (p+1)\) 为奇数的数和为偶数的数。
然后每次查询的时候我们可以通过几次 \(lower_bound\) 来解决。
复杂度 \(O(m\log n)\space or\space O(m\sqrt{n}\log n)\)
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<int*,int*> pa;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 100010;
int n,q,p;
namespace work1{
int T[maxn<<2],tag[maxn<<2],a[maxn];
inline void push_down(int rt,int l,int r){
if(l == r || tag[rt] == 0) return ;
int mid = l+r >> 1;
tag[rt<<1] ^= 1;
if((mid-l+1)&1) T[rt<<1] ^= 1;
tag[rt<<1|1] ^= 1;
if((r-mid)&1) T[rt<<1|1] ^= 1;
tag[rt] = 0;
}
void build(int rt,int l,int r){
if(l == r){
T[rt] = a[l]&1;
return ;
}int mid = l+r >> 1;
build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
T[rt] = T[rt<<1]+T[rt<<1|1] & 1;
}
int L,R;
void modify(int rt,int l,int r){
if(L <= l && r <= R){
tag[rt] ^= 1;
if((r-l+1)&1) T[rt] ^= 1;
return ;
}int mid = l+r >> 1;push_down(rt,l,r);
if(L <= mid) modify(rt<<1,l,mid);
if(R > mid) modify(rt<<1|1,mid+1,r);
T[rt] = T[rt<<1]+T[rt<<1|1] & 1;
}
int query(int rt,int l,int r){
if(L <= l && r <= R) return T[rt];
int mid = l+r >> 1;push_down(rt,l,r);
if(R <= mid) return query(rt<<1,l,mid);
if(L > mid) return query(rt<<1|1,mid+1,r);
return query(rt<<1,l,mid) + query(rt<<1|1,mid+1,r) & 1;
}
int main(){
rep(i,1,n) read(a[i]);
build(1,1,n);
int op,x;
while(q--){
read(op);
if(op == 0){
read(L);read(R);read(x);
if(x & 1) modify(1,1,n);
}else{
read(L);read(R);
printf("%d\n",query(1,1,n));
}
}
return 0;
}
}
namespace work2{
const int maxm = 322;
int tmp[maxn],c[maxn];
struct Node{
int a[maxm],b[maxm],tag;
int cnta,cntb,l,r;
// a[i] % (p+1) = 1;
// b[i] % (p+1) = 0;
void build(int n){
sort(tmp+1,tmp+n+1);
cnta = cntb = 0;
rep(i,1,n){
if(tmp[i] % (p+1) & 1) a[++cnta] = tmp[i];
else b[++cntb] = tmp[i];
}return ;
}
int query_all(int &one,int &two){
int x = (p - tag + (p+1)) % (p+1);pa pos;
if(x & 1) pos = equal_range(a+1,a+cnta+1,x);
else pos = equal_range(b+1,b+cntb+1,x);
two += (pos.second - pos.first);
if(tag <= (p-1)){
x = p - 1 - tag;int ps = 0;
if(x & 1) ps = upper_bound(a+1,a+cnta+1,x) - a - 1;
else ps = upper_bound(b+1,b+cntb+1,x) - b - 1;
one += ps;
}
if(tag >= 2){
x = p - tag;int ps = 0;
if(x & 1) ps = cnta - (upper_bound(a+1,a+cnta+1,x)-a-1);
else ps = cntb - (upper_bound(b+1,b+cntb+1,x)-b-1);
one += ps;
}
}
void query(int l,int r,int &one,int &two){
int cnt = 0;
rep(i,this->l,this->r){
c[i] += tag;
if(c[i] >= p+1) c[i] -= p+1;
tmp[++cnt] = c[i];
}sort(tmp+1,tmp+cnt+1);
cnta = cntb = tag = 0;
rep(i,1,cnt){
if(tmp[i] % (p+1) & 1) a[++cnta] = tmp[i];
else b[++cntb] = tmp[i];
}
rep(i,l,r){
if(c[i] % (p+1) == p) ++ two;
else if(c[i] % (p+1) & 1) ++ one;
}return ;
}
void modify(int l,int r,int x){
int cnt = 0;
rep(i,this->l,this->r){
c[i] += tag;if(c[i] >= (p+1)) c[i] -= (p+1);
if(l <= i && i <= r){
c[i] += x;
if(c[i] >= (p+1)) c[i] -= (p+1);
}
tmp[++cnt] = c[i];
}sort(tmp+1,tmp+cnt+1);
cnta = cntb = tag = 0;
rep(i,1,cnt){
if(tmp[i] % (p+1) & 1) a[++cnta] = tmp[i];
else b[++cntb] = tmp[i];
}return ;
}
}zs[maxm];
int belong[maxn];
inline void modify(int l,int r,int x){
if(belong[l] == belong[r]) return zs[belong[l]].modify(l,r,x);
zs[belong[l]].modify(l,zs[belong[l]].r,x);
zs[belong[r]].modify(zs[belong[r]].l,r,x);
rep(i,belong[l]+1,belong[r]-1){
zs[i].tag += x;
if(zs[i].tag >= (p+1)) zs[i].tag -= (p+1);
}
return ;
}
inline int query(int l,int r){
int res1 = 0,res2 = 0;
if(belong[l] == belong[r]){
zs[belong[l]].query(l,r,res1,res2);
}else{
zs[belong[l]].query(l,zs[belong[l]].r,res1,res2);
zs[belong[r]].query(zs[belong[r]].l,r,res1,res2);
rep(i,belong[l]+1,belong[r]-1) zs[i].query_all(res1,res2);
}
if((res1 & 1) || (res2 & 1)) return 1;
else return 0;
}
int main(){
int block = ceil(sqrt(n));
int sz = 0,m = 1;
zs[1].l = 1;
rep(i,1,n){
belong[i] = m;read(tmp[++sz]);
c[i] = (tmp[sz] %= (p+1));
if(sz == block){
zs[m].build(sz);
zs[m].r = i,zs[++m].l = i+1;
sz = 0;
}
}
if(zs[m].l != n+1){
zs[m].r = n;
zs[m].build(n-zs[m].l+1);
}else --m;
int op,l,r,x;
while(q--){
read(op);read(l);read(r);
if(op == 0) read(x),modify(l,r,x % (p+1));
else printf("%d\n",query(l,r));
}
return 0;
}
}
int main(){
read(n);read(q);read(p);
if(p & 1) work1::main();
else work2::main();
return 0;
}
loj #6138. 「2017 山东三轮集训 Day4」Right的更多相关文章
- loj #6136. 「2017 山东三轮集训 Day4」Left
题目: 题解: 我们可以发现所有的交换器都是一个位置连接着下一层左侧的排序网络,另一个位置连着另一侧的排序网络. 而下一层是由两个更低阶的排序网络构成的. 两个网络互不干扰.所以我们可以通过第一行和最 ...
- Loj #6142. 「2017 山东三轮集训 Day6」A
link: https://loj.ac/problem/6142 推完一波式子之后发现求的是:ΣC(N,i)^2, 其中i是偶数. 然后就可以卢卡斯乱搞了,分奇偶和之前的答案合并就好了233. #i ...
- LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树
这个就比较简单了~ Code: #include <cstdio> #include <algorithm> #define N 100004 #define inf 1000 ...
- 「2017 山东三轮集训 Day1」Flair
模拟赛的题 好神仙啊 题面在这里 之前的Solution很蠢 现在已经update.... 题意 有$ n$个商品价格均为$ 1$,您有$ m$种面值的货币,面值为$ C_1..C_m$ 每种物品你有 ...
- 【loj6142】「2017 山东三轮集训 Day6」A 结论题+Lucas定理
题解: 当奇数 发现答案就是C(n,1)^2+C(n,3)^2+...C(n,n)^2 倒序相加,发现就是C(2n,n) 所以答案就是C(2n,n)/2 当偶数 好像并不会证 打表出来可以得到 2.当 ...
- 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树
题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...
- 「2017 山东三轮集训 Day7」Easy
一棵带边权的树,多次询问 $x$ 到编号为 $[l,r]$ 的点最短距离是多少 $n \leq 100000$ sol: 动态点分治,每层重心维护到所有点的距离 查询的时候在管辖这个点的 log 层线 ...
- #6145. 「2017 山东三轮集训 Day7」Easy 动态点分治
\(\color{#0066ff}{题目描述}\) JOHNKRAM 最近在参加 C_SUNSHINE 举办的聚会. C 国一共有 n 座城市,这些城市由 n−1 条无向道路连接.任意两座城市之间有且 ...
- 「2017 山东三轮集训 Day7 解题报告
「2017 山东三轮集训 Day7」Easy 练习一下动态点分 每个点开一个线段树维护子树到它的距离 然后随便查询一下就可以了 注意线段树开大点... Code: #include <cstdi ...
随机推荐
- ASP.NET MVC Bootstrap模板选中菜单高亮显示当前项方法
当我们处理后台显示当前页面,当前页菜单项高亮,我们可以使用js方法,也可用程序实现,使用Bootstrap模板处理高亮并展开方法之一 1.在项目中导入 <script src="/as ...
- spark集群安装
cd到conf中去 修改名字 mv spark-env.sh.template spark-env.sh 并且修改内容 添加: export JAVA_HOME=/root/java/jdk1.8 ...
- ThinkPHP3.2添加scws中文分词
前言 前一段时间,公司网站做站内搜索,只简单针对输入的文字进行搜索,作全匹配检索,搜索出来的内容很少.如何达到模糊搜索,匹配到更多的内容成了需要解决的问题.于是,今天想到可以做分词检索,如何对输入的一 ...
- ixgbe RSS原理分析
这个月,一直在搞ixgbe RSS,希望能使得收包均衡,结果没成功,但是对网卡的收包原理理解得更深入些. 1.网卡硬件通过网线或者光纤收包. 2.网卡的RSS功能根据网络五元组计算得到32bit的ha ...
- Pandas日期功能
日期功能扩展了时间序列,在财务数据分析中起主要作用.在处理日期数据的同时,我们经常会遇到以下情况 - 生成日期序列 将日期序列转换为不同的频率 创建一个日期范围 通过指定周期和频率,使用date.ra ...
- 一块网卡多个IP实现
////////////////////////////写在前面//////////////////////////////////////////// 需要注意,这里我们是一块网卡多个IP,而并非是 ...
- js中的数组对象中的方法解析
concat()方法: 合并两个数组,返回新对象的结果: join()方法 : 把数组内的所有元素加入到一个字符串中,传入的分隔符就是指定的分隔符 pop()方法: 删除数组并返回数组的最后一个元 ...
- Linux软件安装(二)
1. 安装软件时,如果依赖的文件是 .so 类型的文件(so文件是谋个文件的小功能模块,如果php.ini中设置的模块引用就是 .so文件) ,这时被依赖的软件要安装完整的软件,一般可以根据 .so ...
- 负载均衡之HTTP重定向
转载请说明出处:http://blog.csdn.net/cywosp/article/details/38014581 由于目前现有网络的各个核心部分随着业务量的提高,访问量和数据流量的快速增长,其 ...
- 分享知识-快乐自己:MYSQL之內链接 左链接 右链接 区别
MYSQL中可以通过内外键链接,将有关系的表中数据合并到一起进行条件筛选: 首先创建两个新表,数据如下: student 表数据: score 表数据: 可以看到students表中stu_id为16 ...