【LOJ】#2492. 「BJOI2018」二进制
题解
每次开这样的数据结构题感想都大概是如下两点
1.为什么别人代码长度都是我的1/2????
2.为什么我运行时间都是他们的两倍????
简单分析一下,我们关注一个区间是否合法只关注这个区间有多少个1,有多少个0
有偶数个1,一定合法,因为3的二进制是11,我们只需要111111拼起来一定除得开3
只有一个1,一定不合法,因为必然质因数只有2
有奇数个且大于一个1,没有0,一定不合法,我们两两消掉11,最后会剩下一个除不开的1
有奇数个且大于一个1,有一个0,一定不合法,我们两两消掉11,最后会剩下一个10或者01,也除不开
有奇数个且大于一个1,有两个0,一定合法,10101是一个合法的,剩下的两两消掉11即可
分析完了想怎么维护吧,反着比正着好维护,就考虑用总方案数减掉只有一个1的区间,和有奇数个且大于1个1而且0的个数小于2个的区间
分析了完了就是分类讨论大题了= =
先讨论第一种
我现在有线段树上左右两个区间
左边是
010001000
右边是
001000100
我显然要用右边的[1,2]和左边的[3,6]搭配,右边的[3,6]和左边的[7,10]搭配
所以我们维护每个区间最靠左的两个1的下标,最靠右的两个1的下标,剩下的小情况就讨论一下好了
有奇数个且大于1个1而且0的个数小于2的个数
左边是
1101101111
1111011101
我要用右边的[1,4]和左边[7,10]搭配,且1的个数有奇数个
还有右边[1,4]和左边[4,6]搭配,1的个数有奇数个
右边[5,8]和左边[7,10]搭配,1的个数有奇数个
我们每段右区间搭配的时候显然相邻两个会占另一半区间的所有,所以最后如果右边区间长度是奇数分类讨论一下就好
题解
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define MAXN 100005
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,M;
int a[MAXN];
struct node {
int L,R;
pii l[2],r[2];
int64 sum[2];
}tr[MAXN * 4];
void update(int u);
int64 Query0(int u,int l,int r,pii &zero);
int64 Query1(int u,int l,int r,pii &one);
void build(int u,int l,int r);
void check(pii &t,int v,int op) {
if(op == 0) {
if(v < t.se) t.se = v;
if(t.se < t.fi) swap(t.fi,t.se);
}
else {
if(v > t.se) t.se = v;
if(t.se > t.fi) swap(t.fi,t.se);
}
}
void update(int u) {
for(int i = 0 ; i <= 1 ; ++i) tr[u].sum[i] = tr[u << 1].sum[i];
int mid = (tr[u].L + tr[u].R) >> 1;
pii t;
t = tr[u << 1].r[0];tr[u].sum[0] += Query0(u << 1 | 1,mid + 1,tr[u].R,t);
t = tr[u << 1].r[1];tr[u].sum[1] += Query1(u << 1 | 1,mid + 1,tr[u].R,t);
for(int i = 0 ; i <= 1 ; ++i) {
tr[u].l[i] = mp(tr[u].R + 1,tr[u].R + 1);
tr[u].r[i] = mp(tr[u].L - 1,tr[u].L - 1);
if(tr[u << 1].l[i].fi <= mid) check(tr[u].l[i],tr[u << 1].l[i].fi,0);
if(tr[u << 1].l[i].se <= mid) check(tr[u].l[i],tr[u << 1].l[i].se,0);
check(tr[u].l[i],tr[u << 1 | 1].l[i].fi,0);
check(tr[u].l[i],tr[u << 1 | 1].l[i].se,0);
if(tr[u << 1 | 1].r[i].fi > mid) check(tr[u].r[i],tr[u << 1 | 1].r[i].fi,1);
if(tr[u << 1 | 1].r[i].se > mid) check(tr[u].r[i],tr[u << 1 | 1].r[i].se,1);
check(tr[u].r[i],tr[u << 1].r[i].fi,1);
check(tr[u].r[i],tr[u << 1].r[i].se,1);
}
}
int64 Query1(int u,int l,int r,pii &one) {
if(tr[u].L == l && tr[u].R == r) {
int64 res = 0;
if(l < tr[u].l[1].fi) {
res += (tr[u].l[1].fi - l) * (one.fi - one.se);
}
if(tr[u].l[1].fi < tr[u].l[1].se){
res += (tr[u].l[1].se - tr[u].l[1].fi) * (l - 1 - one.fi);
}
if(tr[u].r[1].fi >= l) check(one,tr[u].r[1].fi,1);
if(tr[u].r[1].se >= l) check(one,tr[u].r[1].se,1);
return res + tr[u].sum[1];
}
int mid = (tr[u].L + tr[u].R) >> 1;
if(r <= mid) return Query1(u << 1,l,r,one);
else if(l > mid) return Query1(u << 1 | 1,l,r,one);
else return Query1(u << 1,l,mid,one) + Query1(u << 1 | 1,mid + 1,r,one);
}
int up(int A,int B) {
if(A % B == 0) return A / B;
return A / B + 1;
}
int64 Query0(int u,int l,int r,pii &zero) {
if(tr[u].L == l && tr[u].R == r) {
int64 res = 0;
if(l < tr[u].l[0].fi) {
int t = tr[u].l[0].fi - l;
if(l - 1 > zero.fi) {
res += t / 2 * (l - 1 - zero.fi);
if(t & 1) {
res += (l - 1 - zero.fi) / 2;
}
}
if(zero.fi > zero.se) {
res += t / 2 * (zero.fi - zero.se - 1);
if(t & 1) {
if(l - 1 - zero.fi & 1) res += up(zero.fi - zero.se - 1,2);
else res += (zero.fi - zero.se - 1) / 2;
}
if(l - 1 - zero.fi & 1) res += t / 2;
else res += up(t,2);
if(zero.fi == l - 1) --res;
}
}
if(tr[u].l[0].fi < tr[u].l[0].se) {
int t = tr[u].l[0].se - tr[u].l[0].fi;
if(l - 1 > zero.fi) {
res += t / 2 * (l - 1 - zero.fi);
if(tr[u].l[0].fi == l) --res;
if(t & 1) {
if(tr[u].l[0].se - l - 1 & 1) res += (l - 1 - zero.fi) / 2;
else res += up(l - 1 - zero.fi,2);
}
}
}
if(tr[u].r[0].fi >= l) check(zero,tr[u].r[0].fi,1);
if(tr[u].r[0].se >= l) check(zero,tr[u].r[0].se,1);
return res + tr[u].sum[0];
}
int mid = (tr[u].L + tr[u].R) >> 1;
if(r <= mid) return Query0(u << 1,l,r,zero);
else if(l > mid) return Query0(u << 1 | 1,l,r,zero);
else return Query0(u << 1,l,mid,zero) + Query0(u << 1 | 1,mid + 1,r,zero);
}
void build(int u,int l,int r) {
tr[u].L = l;tr[u].R = r;
tr[u].sum[0] = tr[u].sum[1] = 0;
if(l == r) {
for(int i = 0 ; i <= 1 ; ++i) {
tr[u].l[i] = mp(r + 1,r + 1);
tr[u].r[i] = mp(l - 1,l - 1);
if(a[l] == i) {
check(tr[u].l[i],l,0);
check(tr[u].r[i],l,1);
}
}
if(a[l] == 1) tr[u].sum[1] = 1;
return;
}
int mid = (l + r) >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
update(u);
}
void Change(int u,int pos) {
if(tr[u].L == tr[u].R) {
tr[u].sum[0] = tr[u].sum[1] = 0;
for(int i = 0 ; i <= 1 ; ++i) {
tr[u].l[i] = mp(pos + 1,pos + 1);
tr[u].r[i] = mp(pos - 1,pos - 1);
if(a[pos] == i) {
check(tr[u].l[i],pos,0);
check(tr[u].r[i],pos,1);
}
}
if(a[pos] == 1) tr[u].sum[1] = 1;
return;
}
int mid = (tr[u].L + tr[u].R) >> 1;
if(pos <= mid) Change(u << 1,pos);
else Change(u << 1 | 1,pos);
update(u);
}
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) read(a[i]);
build(1,1,N);
read(M);
int op,l,r;
for(int i = 1 ; i <= M ; ++i) {
read(op);read(l);
if(op == 1) {
a[l] ^= 1;Change(1,l);
}
else {
read(r);
int64 res = 1LL * (r - l + 1) * (r - l + 2) / 2;
pii t;
res -= Query0(1,l,r,t = mp(l - 1,l - 1));
res -= Query1(1,l,r,t = mp(l - 1,l - 1));
out(res);enter;
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
【LOJ】#2492. 「BJOI2018」二进制的更多相关文章
- loj#2016. 「SCOI2016」美味
题目链接 loj#2016. 「SCOI2016」美味 题解 对于不带x的怎么做....可持久化trie树 对于带x,和trie树一样贪心 对于答案的二进制位,从高往低位贪心, 二进制可以表示所有的数 ...
- 「BJOI2018」链上二次求和
「BJOI2018」链上二次求和 https://loj.ac/problem/2512 我说今天上午写博客吧.怕自己写一上午,就决定先写道题. 然后我就调了一上午线段树. 花了2h找到lazy标记没 ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- Loj #3059. 「HNOI2019」序列
Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...
- Loj #3056. 「HNOI2019」多边形
Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...
随机推荐
- github如何添加新的分支
需求:甲建立分支分给乙步骤:在甲创建的项目仓库里边点右上角的按钮 就可以通过名字搜索了. 在乙的右上角 再选中Repositories就可以看到所有的 存储库 了
- Django_博客_XSS 攻击防范
背景: 博客项目中用户后台添加文章时,若通过富文本编辑器输入 标签内容或者 js 指令会导致文章排版错乱,甚至进行XSS攻击 攻击现象: 文本内容输入 js 指令 文章描述时正确显示其文本内容 但在打 ...
- 【刷题】BZOJ 4078 [Wf2014]Metal Processing Plant
Description 定义集合S的价值D(S)为: 现在给你n个元素,并给出其中任意两个元素之间的d(i,j)值 要你将这些元素划分成两个集合A.B. 求min{D(A)+D(B)}. 注:d(i, ...
- 学习6__STM32--SPI外设之中断收发---
<目标> STM32双机 SPI中断收发通信 <描述> # STM32双机配置为一主一从模式 # 采用主机中断发送,从机中断接收 # 收发机制采用不间断收发(发送为空就发送,接 ...
- 51nod1229 序列求和 V2 【数学】
题目链接 B51nod1229 题解 我们要求 \[\sum\limits_{i = 1}^{n}i^{k}r^{i}\] 如果\(r = 1\),就是自然数幂求和,上伯努利数即可\(O(k^2)\) ...
- 洛谷 P1852 [国家集训队]跳跳棋 解题报告
P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...
- [SDOI2017]硬币游戏
考虑生成函数来做 g(x)函数就是0+0*x+...+1*x^s+...+|∑|^(n-s)x^n 就是最后s位必须填这个串,但是前面随便填的方案数 然后枚举之前出现了哪个串(包括自己),如果没有相交 ...
- Mac 删除应用卸载后无法正常移除的图标
经常会不通过appstore下载软件,也就是从网页中下载dmg,自己安装,但是当我不再想要这个软件,然后把它卸载掉之后就会发现,launchpad里还是遗留了这个软件的图标,而且删不掉.这个时候,就可 ...
- 各种蕴含算法思想的DP - 2
study from: https://www.cnblogs.com/flashhu/p/9480669.html 3.斜率dp study from:http://www.cnblogs.com/ ...
- Hadoop基础-MapReduce的Partitioner用法案例
Hadoop基础-MapReduce的Partitioner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Partitioner关键代码剖析 1>.返回的分区号 ...