Description

pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是333 的倍数。他想研究对于二进

制,是否也有类似的性质。于是他生成了一个长为n 的二进制串,希望你对于这个二进制串的一个子区间,能求出

其有多少位置不同的连续子串,满足在重新排列后(可包含前导0 )是一个3 的倍数。两个位置不同的子区间指开

始位置不同或结束位置不同。由于他想尝试尽量多的情况,他有时会修改串中的一个位置,并且会进行多次询问。

Solution

假设知道结论:

当一个二进制数满足以下任意条件则重排后不能 \(\mod 3=0\)

1.只出现了一个 \(1\)

2.\(1\) 出现的次数为奇数,且 \(0\) 出现的为 \(0\)

3.\(1\) 出现的次数为奇数,且 \(0\) 出现的为 \(1\)

证明:

\(1\) 容易证明

\(2,3\) 的话,我们首先要知道 \(2^2 \mod 3=1\) ,且 \(*2^2\) 之后依旧满足

\(2^1 \mod 3=2\),且 \(*2^2\) 之后依旧满足

所以有结论:放在偶数位可以贡献 \(2\),放在奇数位贡献 \(1\)

那么如果 \(1\) 出现了偶数次那么一定可以满足条件,因为把 \(1\) 都放在后面,恰好可以构成数 \(2^k-1\),而 \(2^k \mod 3=1\)

那么如果奇数位上放 \(1\) 的个数比偶数位多了 \(3\),那么一定可以拼成满足 \(\mod 3=0\)

因为奇偶配对之后 \(\mod 3=0\),剩下的奇数位 \(3*2 \mod 3=0\),所以恰好满足

\(1\) 出现次数为奇数,且 \(0\) 出现次数为 \(>=3\),显然满足

\(1\) 出现次数为奇数,且 \(0\) 出现次数为 \(=2\),由于总共有奇数位,所以奇数比偶数本身就多 \(1\) ,也满足

\(0\) 出现次数为 \(0,1\) 时 ,也显然不满足

综上只需要维护不合法情况:

1.只出现了一个 \(1\)

2.\(1\) 出现的次数为奇数,且 \(0\) 出现的为 \(0\)

3.\(1\) 出现的次数为奇数,且 \(0\) 出现的为 \(1\)

\(1\) 情况和 \(2,3\) 有交集,我们强制 \(1\) 条件为 "出现了一个\(1\),且 \(0\) 出现了至少 \(2\) 次"

线段树分别维护 \(dl/dr[2][2]\) 表示经过左/右端点,\(0\) 出现了 \(0/1\) 次,\(1\) 出现次数的奇偶性的方案数 (统计情况 \(2,3\))

\(fl/r[3]\) 表示经过左/右端点,\(1\) 恰好出现了 \(1\) 次,且 \(0\) 出现的次数分别为 \(0,1,>=2\) 的方案数 (统计情况 \(1\))

\(l/r0\) 表示经过左右端点的连续 \(0\) 的长度

\(c0,c1\) \(0,1\) 的个数

#include<bits/stdc++.h>
#define ls (o<<1)
#define rs (o<<1|1)
using namespace std;
template<class T>void gi(T &x){
int f;char c;
for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
typedef long long ll;
const int N=1e5+10;
int n,a[N],Q,op,x,y;
struct data{
ll s,dl[2][2],dr[2][2],fl[3],fr[3],l0,r0;int c0,c1;
inline void init(){
for(int i=0;i<2;i++)for(int j=0;j<2;j++)dl[i][j]=dr[i][j]=0;
fl[0]=fl[1]=fr[0]=fr[1]=fl[2]=fr[2]=l0=r0=s=c0=c1=0;
}
data(){init();}
}tr[N*4];
inline data merge(data A,data B){
data R;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++){
R.dl[i][j]+=A.dl[i][j];R.dr[i][j]+=B.dr[i][j];
if(i>=A.c0)R.dl[i][j]+=B.dl[i-A.c0][j^(A.c1&1)];
if(i>=B.c0)R.dr[i][j]+=A.dr[i-B.c0][j^(B.c1&1)];
}
for(int i=0;i<3;i++){
R.fl[i]+=A.fl[i];R.fr[i]+=B.fr[i];
if(!A.c1)R.fl[min(2,i+A.c0)]+=B.fl[i];
if(!B.c1)R.fr[min(2,i+B.c0)]+=A.fr[i];
}
if(A.c1==1 && B.l0)R.fl[min(2ll,A.c0+B.l0)]++,R.fl[2]+=B.l0-1;
if(B.c1==1 && A.r0)R.fr[min(2ll,B.c0+A.r0)]++,R.fr[2]+=A.r0-1;
R.l0=(!A.c1?A.c0+B.l0:A.l0);R.r0=(!B.c1?B.c0+A.r0:B.r0);
R.c0=A.c0+B.c0;R.c1=A.c1+B.c1; R.s+=A.s+B.s;
R.s+=A.dr[0][1]*(B.dl[1][0]+B.dl[0][0]);
R.s+=A.dr[1][0]*B.dl[0][1];
R.s+=A.dr[0][0]*(B.dl[1][1]+B.dl[0][1]);
R.s+=A.dr[1][1]*B.dl[0][0];
if(B.l0)R.s+=(A.fr[2]+A.fr[1])*B.l0,R.s+=A.fr[0]*(B.l0-1);
if(A.r0)R.s+=(B.fl[2]+B.fl[1])*A.r0,R.s+=B.fl[0]*(A.r0-1); return R;
}
inline void rep(data &t,int x){
t.init();
if(x)t.dl[0][1]=t.dr[0][1]=t.c1=t.s=t.fl[0]=t.fr[0]=1;
else t.dl[1][0]=t.dr[1][0]=t.c0=t.l0=t.r0=1;
}
inline void build(int l,int r,int o){
if(l==r){rep(tr[o],a[l]);return ;}
int mid=(l+r)>>1;
build(l,mid,ls);build(mid+1,r,rs);
tr[o]=merge(tr[ls],tr[rs]);
}
inline void ins(int l,int r,int o,int sa){
if(l==r){rep(tr[o],a[l]);return ;}
int mid=(l+r)>>1;
if(sa<=mid)ins(l,mid,ls,sa);
else ins(mid+1,r,rs,sa);
tr[o]=merge(tr[ls],tr[rs]);
}
inline data qry(int l,int r,int o,int sa,int se){
if(sa<=l && r<=se)return tr[o];
int mid=(l+r)>>1;
if(se<=mid)return qry(l,mid,ls,sa,se);
if(sa>mid)return qry(mid+1,r,rs,sa,se);
return merge(qry(l,mid,ls,sa,mid),qry(mid+1,r,rs,mid+1,se));
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)gi(a[i]);
build(1,n,1);
cin>>Q;
while(Q--){
gi(op);gi(x);
if(op==1)a[x]^=1,ins(1,n,1,x);
else{
gi(y);
printf("%lld\n",1ll*(y-x+1)*(y-x+2)/2-qry(1,n,1,x,y).s);
}
}
return 0;
}

bzoj 5294: [Bjoi2018]二进制的更多相关文章

  1. bzoj 5294: [Bjoi2018]二进制【动态dp+线段树】

    不太清楚是不是动态dp--? 这个维护其实和最大连续子段差不多,维护l[x][y],r[x][y],m[x][y]分别表示包含左儿子的01个数为(x,y)的区间个数,包含右儿子的01个数为(x,y)的 ...

  2. 【BZOJ5294】[BJOI2018]二进制(线段树)

    [BZOJ5294][BJOI2018]二进制(线段树) 题面 BZOJ 洛谷 题解 二进制串在模\(3\)意义下,每一位代表的余数显然是\(121212\)这样子交替出现的. 其实换种方法看,就是\ ...

  3. [BZOJ 2989]数列(二进制分组+主席树)

    [BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...

  4. 2019.02.12 bzoj5294: [Bjoi2018]二进制(线段树)

    传送门 题意简述: 给出一个长度为nnn的二进制串. 你需要支持如下操作: 修改每个位置:1变0,0变1 询问对于一个区间的子二进制串有多少满足重排之后转回十进制值为333的倍数(允许前导000). ...

  5. Bzoj5294/洛谷P4428 [Bjoi2018]二进制(线段树)

    题面 Bzoj 洛谷 题解 考虑一个什么样的区间满足重组之后可以变成\(3\)的倍数.不妨设\(tot\)为一个区间内\(1\)的个数.如果\(tot\)是个偶数,则这个区间一定是\(3\)的倍数,接 ...

  6. bzoj 4398 福慧双修——二进制分组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 如果枚举1号点走哪些点出去,就从那些点出发跑多源最短路即可.最短路不会重复经过一条边. ...

  7. bzoj 4398 福慧双修 —— 二进制分组+多起点最短路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 按二进制每一位是 0/1 把 1 号点的儿子分成两组,分别作为起点和终点跑多起点最短路 ...

  8. BZOJ 4140 凸包+二进制分组

    思路: $(x_0-x)^2+(y_0-y)^2<=x^2+y^2$ $y>=(-x_0/y_0)x+(x_0^2+y_0^2)/2y0$ 这显然就是凸包了 以一个斜率不断向下(上)走   ...

  9. BZOJ 3107 [cqoi2013]二进制a+b (DP)

    3107: [cqoi2013]二进制a+b Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 995  Solved: 444[Submit][Stat ...

随机推荐

  1. [SCOI2010]生成字符串 题解(卡特兰数的扩展)

    [SCOI2010]生成字符串 Description lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数 ...

  2. 29、filter、map、reduce的作用?

    通俗的说..都是用在一堆数据(比如一个列表)上.. map是用同样方法把所有数据都改成别的..字面意思是映射..比如把列表的每个数都换成其平方.. reduce是用某种方法依次把所有数据丢进去最后得到 ...

  3. 自动化测试===adb 解锁手机的思路

    在adb里有模拟按键/输入的命令 比如使用 adb shell input keyevent <keycode> 命令,不同的 keycode 能实现不同的功能,完整的 keycode 列 ...

  4. 56.Merge Intervals---贪心---《编程之美》2.19区间重合判断

    题目链接:https://leetcode.com/problems/merge-intervals/description/ 题目大意:给出一串list,里面装interval类,这个类里有star ...

  5. The algorithm of entropy realization

    近似熵的一种快速实用算法 Pincus提出的近似熵算法中有很多冗余的计算,效率低,速度慢,不利于实际应用,洪波等人在定义的基础上引入二值距离矩阵的概率,提出了一种实用快速的算法. function A ...

  6. Apache虚拟主机配置(多个域名访问多个目录)(转)

    Apache虚拟主机配置(多个域名访问多个目录) 为了方便管理虚拟主机,我决定使用一种方法,那就是修改httpd-vhosts.conf文件. 第一步首先要使扩展文件httpd-vhosts.conf ...

  7. YAML中使用Jinja模板以{{ foo }}开头需要整行加双引号

    YAML陷阱 YAML语法要求如果值以{{ foo }}开头的话我们需要将整行用双引号包起来.这是为了确认你不是想声明一个YAML字典.该知识点在 YAML 语法 页面有所讲述. 这样是不行的: - ...

  8. 湖南省第六届省赛题 Biggest Number (dfs+bfs,好题)

    Biggest Number 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 You have a maze with obstacles and non-zero di ...

  9. Linux命令之dig命令实例讲解

    1.查看域名的A记录 # dig yahoo.com; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.10.rc1.el6_3.2 <<> ...

  10. jquery datatable的详细用法

    1,首先需要引用下面两个文件 <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css ...