wannafly 17D 01序列2
水题。
假设有两个二进制数a,b,c=a+b(a,b拼接起来)
那么显然如果b长度为偶数\(c\mod 3=(b\mod 3+a\mod 3)\mod 3\)
否则\(c\mod 3=(b\mod 3+(a\mod 3)*2)\mod 3\)
那么只要记一个区间的前缀和后缀就行了,合并的时候左儿子的后缀和右儿子的前缀合并。
具体见代码
#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
int a[500010];
struct yyb{
bool len;
ll l[3][2],r[3],ans,num;
//len表示长度是奇数/偶数
//l[i][j]表示长度为奇数/偶数膜3余0/1/2的前缀数量
//r[i]表示膜3余0/1/2的前缀数量
//ans表示答案
//num表示这个区间膜3
}s[500010<<2];
il yyb operator +(const yyb&a,const yyb&b){
yyb c;
c.len=a.len^b.len;
for(int i=0;i<3;++i)c.l[i][0]=a.l[i][0],c.l[i][1]=a.l[i][1],c.r[i]=b.r[i];
c.ans=a.ans+b.ans;
for(int i=0;i<3;++i)//答案加上中间部分
for(int j=0;j<3;++j)
for(int k=0;k<2;++k)
if((i*(k?2:1)+j)%3==0)c.ans+=a.r[i]*b.l[j][k];
for(int i=0;i<3;++i)
for(int j=0;j<2;++j)
c.l[(a.num*(j?2:1)+i)%3][j^a.len]+=b.l[i][j];
for(int i=0;i<3;++i)c.r[(i*(b.len?2:1)+b.num)%3]+=a.r[i];
c.num=(a.num*(b.len?2:1)+b.num)%3;
return c;
}
#define mid ((l+r)>>1)
il vd set(int x,int p){
s[x].len=1;
memset(s[x].l,0,sizeof s[x].l);
memset(s[x].r,0,sizeof s[x].r);
s[x].ans=!a[p];s[x].num=a[p];
s[x].l[a[p]][1]=s[x].r[a[p]]=1;
}
il vd build(int x,int l,int r){
if(l==r){set(x,l);return;}
build(x<<1,l,mid),build(x<<1|1,mid+1,r);
s[x]=s[x<<1]+s[x<<1|1];
}
il vd update(int x,int l,int r,const int&p){
if(l==r){set(x,l);return;}
if(p<=mid)update(x<<1,l,mid,p);
else update(x<<1|1,mid+1,r,p);
s[x]=s[x<<1]+s[x<<1|1];
}
il yyb query(int x,int l,int r,const int&L,const int&R){
if(L<=l&&r<=R)return s[x];
if(L<=mid)
if(mid<R)return query(x<<1,l,mid,L,R)+query(x<<1|1,mid+1,r,L,R);
else return query(x<<1,l,mid,L,R);
else return query(x<<1|1,mid+1,r,L,R);
}
int main(){
int n=gi(),m=gi();
for(int i=1;i<=n;++i)a[i]=gi();
build(1,1,n);
int o,l,r;
while(m--){
o=gi(),l=gi();
if(o==1)a[l]^=1,update(1,1,n,l);
else r=gi(),printf("%lld\n",query(1,1,n,l,r).ans);
}
return 0;
}
wannafly 17D 01序列2的更多相关文章
- Wannafly挑战赛17D 01序列2
传送门 先考虑二进制下为3倍数的数的共同特点自己手玩去,可以发现这些数奇数二进制位上的1个数(记为\(a\))和偶数二进制位上的1个数(记为\(b\))在模3意义下相等(\(a \equiv b (m ...
- BUPT复试专题—寻找变化前01序列(2016)
题目描述 给你一个01序列,HDLC协议处理的话,如果出现连续的5个1会补1个0.例如1111110,会变成11111010. 现在给你一个经过HDLC处理后的01序列,你需要找到HDLC处理之前的0 ...
- AcWing3544. 寻找变化前的01序列
题目描述 给你一个 01 序列,HDLC 协议处理的话,如果出现连续的 5 个 1 会补 1 个 0. 例如 1111110,会变成 11111010. 现在给你一个经过 HDLC 处理后的 01 序 ...
- Python补充01 序列的方法
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在快速教程中,我们了解了最基本的序列(sequence).回忆一下,序列包含有定值 ...
- 【动态规划】XMU 1588 01序列计数
题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1588 题目大意: 给n1个0和n2个1,连续的0不超过k1个,连续的1不超过k2个.问 ...
- [Tjoi2016&Heoi2016]排序[01序列]
4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 994 Solved: 546[Sub ...
- 【Biocode】产生三行的seq+01序列
代码说明: sequence.txt与site.txt整合 如下图: sequence.txt: site.txt: 整理之后如下: 蛋白质序列中发生翻译后修饰的位置标记为“1”,其他的位置标记为“0 ...
- scoi2010&&bzoj1858序列操作
[题目描述] lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a ...
- 【BZOJ-1858】序列操作 线段树
1858: [Scoi2010]序列操作 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1961 Solved: 991[Submit][Status ...
随机推荐
- Django的model中创建表
类中的class Meta字段的作用: 第一个作用可以给这个类起名字 在后台的admin中显示这个类名字 class CourseCategory(models.Model): "" ...
- 去除Xcode6创建工程时自带的storyboard
去除Xcode6创建工程时自带的storyboard 1. 删除storyboard文件,并在setting里面清空加载storyboard: 2. 导入ViewController到appDeleg ...
- [翻译] FBLikeLayout
FBLikeLayout This is an UICollectionView layout inspired by the photo section of facebook. This layo ...
- (1)Object类 (2)包装类和数学处理类 (3)String类
1.Object类1.1 基本概念 java.lang.Object类是Java类层次结构的根类,任何类都是Object类的直接/间接子类. 1.2 常用的方法(重点) Object() - 无参构造 ...
- .net mvc HTTP 错误 403.14 - Forbidden Web 服务器被配置为不列出此目录的内容
1. 检查服务器上是否安装了“HTTP重定向”功能和“静态内容压缩”功能(在添加/删除程序或增加角色处安装).这是我所遇到的问题: 2. 应用程序池要被配置为“集成” 3. 把.net 4.0安装在i ...
- September 20th 2017 Week 38th Wednesday
All our dreams can come true if we have the courage to pursue them. 如果我们有勇气去追求梦想,我们的梦想一定可以成为现实. If y ...
- map filter 的func 放在前面
map filter 的func 放在前面 sorted 在后 ( iter.. , key=function')
- redis开启远程连接访问和需要密码的方法
redis默认是不能远程访问的,如果希望多台机子共用redis数据库,那就需要开启redis远程连接访问.既然可以远程连接了,那就需要密码登陆,否则不安全.下面是具体的方法,按照步骤一步一步来就OK了 ...
- python统计磁盘使用情况
#coding:utf-8import os; def SortList(item): return item[1]; def ReadSize(fileName): return flo ...
- Curator 基本API
package bjsxt.curator.base; import java.util.List; import java.util.concurrent.ExecutorService; impo ...