P4428-[BJOI2018]二进制【树状数组,set】

正题

题目链接:https://www.luogu.com.cn/problem/P4428


题目大意

长度为nnn0/10/10/1串要求支持

  1. 修改一个位置
  2. 求区间[l,r][l,r][l,r]有多少个子区间重排后的二进制数可以被三整除

1≤n≤1051\leq n\leq 10^51n105


解题思路

首先有22k%3=1(k∈Z)2^{2k}\%3=1(k\in Z)22k%3=1(kZ)22k+1%3=2(k∈Z)2^{2k+1}\%3=2(k\in Z)22k+1%3=2(kZ)
分三种情况考虑

  • 111111那么显然无论如何都不可以被三整除
  • 2k2k2k111那么我们之间都排在最后面就好了。
  • 2k+12k+12k+1111kkk不能为000),那么有一种方案就是把某个在奇数位置的111放到偶数位置就可以了,此时需要区间的长度至少为2k+32k+32k+3

然后具体分析一下相当于一个区间111的个数不能为111且如果是奇数个那么必须至少有两个000

看起来很复杂可以反过来做分成以下情况

  1. 区间全是111且长度为奇数
  2. 区间有一个000且长度为偶数
  3. 区间只有一个111
  4. 由于222333会重复一种只有一个111和一个000的情况所以需要加回这个方案

第四种是最好维护的,顺便用树状数组记录就好了

然后前三种我们对于0/10/10/1的位置分别开一个setsetset来查询某个位置前驱/后继的0/1。

然后第三种情况我们对于每个111考虑左右的000区间然后记录在树状数组111的位置

对于第二种情况我们考虑对于每个000考虑左右的111然后记录在那个000的位置

对于第一种情况我们之间记录到区间最左端的000处。

然后统计答案的时候要记得把边界的情况考虑

写起来有点麻烦

时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define lowbit(x) (x&-x)
#define ll long long
using namespace std;
const ll N=1e5+10;
ll n,m,a[N],t[N],p[N];
set<ll> s[2];
void Change(ll x,ll val){while(x<=n){t[x]+=val;x+=lowbit(x);}return;
}
ll Ask(ll x){ll ans=0;while(x){ans+=t[x];x-=lowbit(x);}return ans;
}
ll Left(ll op,ll x)
{return (*--s[op].upper_bound(x));}
ll Right(ll op,ll x)
{return (*s[op].lower_bound(x));}
ll Count(ll n)
{return (n+1)/2*(n+2-(n&1))/2;}
ll Caunt(ll n)
{return n*(n+1)/2;}
ll Calc(ll L,ll R)
{return (L/2+1)*((R+1)/2)+((L+1)/2)*(R/2+1);}
void Updata(ll x){if(x<1||x>n)return;if(p[x])Change(x,-p[x]);if(a[x]){ll L=(x-Left(1,x-1)-1),R=(Right(1,x+1)-x-1);p[x]=(L+1)*(R+1)-1;}else{ll L=(x-Left(0,x-1)-1),R=(Right(0,x+1)-x-1);p[x]=Calc(L,R)+Count(R);}if(x<n&&a[x]!=a[x+1])p[x]--;Change(x,p[x]);return;
}
ll Get(ll x,ll l,ll r){ll L=max(Left(0,x-1),l-1),R=min(Right(0,x+1),r+1);L=x-L-1;R=R-x-1;return Calc(L,R);
}
ll Qet(ll x,ll l,ll r){ll L=max(Left(1,x-1),l-1),R=min(Right(1,x+1),r+1);L=x-L-1;R=R-x-1;return (L+1)*(R+1)-1;
}
signed main()
{scanf("%lld",&n);s[0].insert(0);s[0].insert(n+1);s[1].insert(0);s[1].insert(n+1);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]),s[a[i]].insert(i);for(ll i=1;i<=n;i++)Updata(i);scanf("%lld",&m);while(m--){ll op,l,r,x;scanf("%lld",&op);if(op==1){scanf("%lld",&x);s[a[x]].erase(x);a[x]=!a[x];s[a[x]].insert(x);Updata(x);Updata(Left(0,x-1));Updata(Left(1,x-1));Updata(Right(0,x+1));Updata(Right(1,x+1));}else{scanf("%lld%lld",&l,&r);ll ans=(r-l+1)*(r-l+2)/2;if(Left(1,r)<l){printf("%lld\n",ans);continue;}if(Left(0,r)<l){ans-=Count(r-l+1);printf("%lld\n",ans);continue;}ans-=Ask(r)-Ask(l-1);if(r<n&&a[r]!=a[r+1])ans--;ll Ll=Left(0,l-1),Rr=Right(0,r+1),Lr=Left(0,r),Rl=Right(0,l);ans=ans+Get(Rl,1,n)-Get(Rl,l,r);if(Lr!=Rl)ans=ans+Get(Lr,1,n)-Get(Lr,l,r);if(a[r+1])ans=ans+Count(Rr-Lr-1)-Count(r-Lr);if(a[l])ans=ans-Count(Rl-l);Ll=Left(1,l),Rr=Right(1,r),Lr=Left(1,r),Rl=Right(1,l);ans=ans+Qet(Rl,1,n)-Qet(Rl,l,r);if(Lr!=Rl)ans=ans+Qet(Lr,1,n)-Qet(Lr,l,r);
//			if(!a[r])ans=ans+Caunt(Rr-Rl-1)-Caunt(r-Rl);
//			if(!a[l])ans=ans-Caunt(Lr-l);printf("%lld\n",ans);}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021“MINIEYE杯”中国大学生算法设计超级联赛(5)Random Walk 2(推式子+矩阵逆+矩阵乘)

Random Walk 2 【2.4】Gauss-Jordan消元法求矩阵的逆 高斯消元求矩阵的逆&#xff0c;伴随单位矩阵一起消元即可。 [A,I]→[I,A−1][\text A,\text I]\to [\text I,\text A^{-1}][A,I]→[I,A−1] 移项变形&#xff0c;后就是个矩阵的逆&#xff0c;为啥赛时不写&#xff1f;&a…

牛客题霸 [顺时针旋转矩阵] C++题解/答案

牛客题霸 [顺时针旋转矩阵] C题解/答案 题目描述 有一个NxN整数矩阵&#xff0c;请编写一个算法&#xff0c;将矩阵顺时针旋转90度。 给定一个NxN的矩阵&#xff0c;和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于300。 题解&#xff1a; 根据题目要求&#xff0c;先…

数论:扩展欧几里德(洛谷P1516 青蛙的约会)

欧几里德 基本思想&#xff1a;gcd(q,r)gcd(r,q%r); 证明&#xff0c;设q、r的最大公因数为a&#xff0c;则qxa&#xff0c;rya&#xff0c;xy互质 不妨设x>y&#xff08;显然如果小于会在一次gcd运算后交换&#xff09; 则q%r&#xff08;x%y&#xff09;*a 显然,其与r的最…

CF802O-April Fools‘ Problem(hard)【wqs二分,优先队列】

正题 题目链接:https://www.luogu.com.cn/problem/CF802O 题目大意 nnn天每条有aia_iai​和bib_ibi​。 每条可以花费aia_iai​准备至多一道题&#xff0c;可以花费bib_ibi​打印至多一道准备好了的题。 求准备kkk道题最少要花费多少。 1≤k≤n≤51051\leq k\leq n\leq 5\ti…

2021牛客暑期多校训练营3 G-Yu Ling(Ling YueZheng) and Colorful Tree(cdq分治)

G-Yu Ling(Ling YueZheng) and Colorful Tree HOWARLI题解 大致做法就是首先考虑哪些修改可能影响询问&#xff0c;当修改点权是询问的倍数时才可能影响询问。于是考虑把他们放在一起。 首先每次枚举每种询问的倍数&#xff0c;把这些修改和当前询问放在一起&#xff0c;由于…

参加胶东开发者技术大会有感

2015年的时候&#xff0c;也是在12月&#xff0c;我和Bob(https://www.cnblogs.com/nianming/)去北京参加了“全球架构师峰会”&#xff0c;在那次会议上&#xff0c;来自百度、腾讯、阿里巴巴、京东、美团、新浪微博、Twitter等公司的架构师、技术专家们分享了各自在架构方面的…

牛客题霸 [矩阵乘法] C++题解/答案

牛客题霸 [矩阵乘法] C题解/答案 题目描述 给定两个nn的矩阵A和B&#xff0c;求AB。 题解&#xff1a; 都学过矩阵相乘把&#xff0c;[i][k][i][j]*[j][k] 代码&#xff1a; class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&…

专题:数列信息传递问题转化为图论合点问题(ybtoj-数列询问+序列破解)

文章目录前言&#xff1a;一、数列询问&#xff08;取模&#xff09;解析代码二、序列破解&#xff08;奇偶性&#xff09;解析代码thanks for reading&#xff01;前言&#xff1a; 在一个数列a中&#xff0c;对于一个大区间A和组成它的两个小区间a&#xff0c;b&#xff1b;…

CF786C-Till I Collapse【树状数组倍增,优先队列】

正题 题目链接:https://www.luogu.com.cn/problem/CF786C 题目大意 给出一个长度为nnn的序列。 对于每个k∈[1,n]k\in[1,n]k∈[1,n]求将nnn分成最少的段使得每段的长度不同。 1≤ai≤n≤1051\leq a_i\leq n\leq 10^51≤ai​≤n≤105 解题思路 考虑对于一个kkk我们的做法显然…

Docker最全教程——从理论到实战(五)

在笔者参加腾讯容器服务技术交流会时&#xff0c;我们了解到了藏区牧民的目前的生活艰辛状况&#xff0c;因此除了在同事朋友之间推荐其土特产之外&#xff0c;我们也在此进行初步分享&#xff0c;希望略尽绵薄之力&#xff0c;能够帮助到他们&#xff1a;货真价实、确保都是37…

2021牛客暑期多校训练营6 J-Defend Your Country(无向图点双+思维)

无向图联通分量 点u是割点&#xff0c;当且仅当 特判树根&#xff1a;u为树根&#xff0c;且u有多于1棵子树u不为树根&#xff0c;在递归树上u存在子节点v&#xff0c;满足&#xff1a;dfnu≤lowv\text{dfn}_u\leq \text{low}_vdfnu​≤lowv​ 如上图&#xff0c;v想走到u的组…

牛客题霸 [比较版本号] C++题解/答案

牛客题霸 [比较版本号] C题解/答案 题目描述 如果version1 > version2 返回1&#xff0c;如果 version1 < version2 返回-1&#xff0c;不然返回0. 输入的version字符串非空&#xff0c;只包含数字和字符.。.字符不代表通常意义上的小数点&#xff0c;只是用来区分数字…

不止代码:循环比赛(分治)

循环比赛日程表&#xff08;match&#xff09; 【问题描述】 解析 dfs或分治 分治可以不断递归4个小正方形 左上右下为前一半&#xff0c;左下右上后一半 dfs就很无脑了 代码 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath…

P4983-忘情【wqs二分,斜率优化】

正题 题目链接:https://www.luogu.com.cn/problem/P4983 题目大意 给出长度为nnn的序列xxx&#xff0c;记平均数为xˉ\bar{x}xˉ&#xff0c;要求将序列分成mmm段。 每一段[l,r][l,r][l,r]的值为 ((∑ilrxixˉ)xˉ)2xˉ2\frac{((\sum_{il}^rx_i\times \bar x)\bar x)^2}{\bar…

前瞻科技,引领未来!Microsoft Connect(); 2018即将重磅来袭!

怎么用一句话点燃全球的开发者&#xff1f;——Microsoft Connect(); 2018即将重磅来袭&#xff01;每一个观点都能引发科技狂潮&#xff0c;每一项技术都将提速技术进程&#xff0c;由微软举办的 Microsoft Connect(); 2018 即将在太平洋时间12月4日8:30拉开帷幕&#xff01;大…

2021“MINIEYE杯”中国大学生算法设计超级联赛(7)Yiwen with Formula(任意模数FFT)

Yiwen with Formula 溢流眼泪题解 生成函数化成n个多项式乘积&#xff0c;然后分治把他们依次相乘&#xff0c;需要由于指数需要modϕ(998244353)998244353−1\bmod \phi(998244353)998244353-1modϕ(998244353)998244353−1&#xff0c;因此需要任意模数的FFT。。。 常数贼大…

牛客题霸 [ 孩子们的游戏] C++题解/答案

牛客题霸 [ 孩子们的游戏] C题解/答案 题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开…

4.1模拟报告

总结 做的很坎坷。。。 一些细节上的玄学bug &#xff08;上次也一样。。。&#xff09; 还是要加强基础&#xff01;&#xff01;&#xff01; T1 x的实根 不贴了&#xff0c;就是水题。。。 T2 二分查找 就是lowerbound T3逆序对 1.树状数组 2.归并排序 注意&#xff…

P5048-[Ynoi2019 模拟赛]Yuno loves sqrt technology III【分块】

正题 题目链接:https://www.luogu.com.cn/problem/P5048 题目大意 就是这个 【QA】区间众数&#xff0c;但空间很小 长度为nnn的序列&#xff0c;要求支持查找区间众数出现次数。 强制在线 1≤n,m≤51051\leq n,m\leq 5\times 10^51≤n,m≤5105 解题思路 空间小就不能用蒲公…

2021牛客暑期多校训练营7 J-xay loves Floyd(最短路+bitset优化集合交)

J-xay loves Floyd ANJHZ题解 abcdhhhh_题解 如果di,jwi,j\text d_{i,j}\text w_{i,j}di,j​wi,j​,那么按照题意中的算法仍然能得到正确的结果。此时记cani,j1\text{can}_{i,j}1cani,j​1。 如果存在vvv&#xff0c;使得①cani,v1\text{can}_{i,v}1cani,v​1②canv,j1\text{…