传送门


因为每一位\(\mod 3\)的值为\(1,2,1,2,...\),也就相当于\(1,-1,1,-1,...\)

所以当某个区间的\(1\)的个数为偶数的时候,一定是可行的,只要把这若干个\(1\)放在一起就可以了。

而当某个区间的\(1\)的个数为奇数的时候,那么最优的方式显然是\(1\)和\(-1\)两两配对,剩下\(3\)个\(1\),然后留下至少\(2\)个\(0\),将\(111\)拼成\(10101\)的形式。

注意到\(1\)的个数为\(1\)的时候显然不可行。

所以合法的区间需要满足:\(1\)的个数大于\(1\)、个数为偶数或者个数为奇数且\(0\)的个数\(\geq 2\)

为了方便计算我们将合法区间数量变为总区间数量减去不合法区间数量,而不合法区间需要满足:\(1\)的个数为\(1\),或者个数为奇数且\(0\)的个数\(\leq 1\)

使用线段树维护区间不合法区间数量,对于每一个节点可以维护:区间中不合法区间数量、区间\(0/1\)个数、\(1\)的个数为\(0/1\)的前缀/后缀个数、\(1\)的个数为奇数/偶数且\(0\)的个数为\(0/1\)的前缀/后缀个数、区间左端和右端的数字,就可以计算答案。注意pushup的细节,不要打错就好。

还有一个需要注意的地方:如果用上面的方法,\(10\)和\(01\)两种区间会被重复计算,要在计算的时候减掉。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;inline int read(){int a = 0;char c = getchar();while(!isdigit(c)) c = getchar();while(isdigit(c)){a = a * 10 + c - 48;c = getchar();}return a;
}const int MAXN = 1e5 + 7;
#define int long long
int N , M;
namespace segTree{struct node{int sum , cnt0 , cnt1 , l , r , lft1[2] , rht1[2] , lft[2][2] , rht[2][2];}Tree[MAXN << 2];#define lch (x << 1)
#define rch (x << 1 | 1)
#define mid ((l + r) >> 1)node pushup(node a , node b){node t;t.l = a.l; t.r = b.r;t.sum = a.sum + b.sum - (a.r ^ b.l);t.sum += a.rht1[1] * b.lft1[0] + a.rht1[0] * b.lft1[1];t.sum += (a.rht[1][0] + a.rht[1][1]) * (b.lft[0][0] + b.lft[0][1]) - a.rht[1][1] * b.lft[0][1];t.sum += (a.rht[0][1] + a.rht[0][0]) * (b.lft[1][0] + b.lft[1][1]) - a.rht[0][1] * b.lft[1][1];t.cnt0 = a.cnt0 + b.cnt0; t.cnt1 = a.cnt1 + b.cnt1;t.lft1[0] = a.lft1[0] + (a.cnt1 == 0 ? b.lft1[0] : 0);t.lft1[1] = a.lft1[1] + (a.cnt1 == 0 ? b.lft1[1] : (a.cnt1 == 1 ? b.lft1[0] : 0));t.rht1[0] = b.rht1[0] + (b.cnt1 == 0 ? a.rht1[0] : 0);t.rht1[1] = b.rht1[1] + (b.cnt1 == 0 ? a.rht1[1] : (b.cnt1 == 1 ? a.rht1[0] : 0));bool f1 = a.cnt1 & 1 , f2 = b.cnt1 & 1;t.lft[0][0] = a.lft[0][0] + (a.cnt0 == 0 ? b.lft[f1][0] : 0);t.lft[0][1] = a.lft[0][1] + (a.cnt0 == 0 ? b.lft[f1][1] : (a.cnt0 == 1 ? b.lft[f1][0] : 0));t.lft[1][0] = a.lft[1][0] + (a.cnt0 == 0 ? b.lft[!f1][0] : 0);t.lft[1][1] = a.lft[1][1] + (a.cnt0 == 0 ? b.lft[!f1][1] : (a.cnt0 == 1 ? b.lft[!f1][0] : 0));t.rht[0][0] = b.rht[0][0] + (b.cnt0 == 0 ? a.rht[f2][0] : 0);t.rht[0][1] = b.rht[0][1] + (b.cnt0 == 0 ? a.rht[f2][1] : (b.cnt0 == 1 ? a.rht[f2][0] : 0));t.rht[1][0] = b.rht[1][0] + (b.cnt0 == 0 ? a.rht[!f2][0] : 0);t.rht[1][1] = b.rht[1][1] + (b.cnt0 == 0 ? a.rht[!f2][1] : (b.cnt0 == 1 ? a.rht[!f2][0] : 0));return t;}void init(int x , int l , int r){if(l == r){Tree[x].cnt0 = !(Tree[x].sum = Tree[x].cnt1 = read());Tree[x].lft[1][0] = Tree[x].rht[1][0] = Tree[x].lft1[1] = Tree[x].rht1[1] = Tree[x].l = Tree[x].r = Tree[x].cnt1;Tree[x].lft[0][1] = Tree[x].rht[0][1] = Tree[x].lft1[0] = Tree[x].rht1[0] = Tree[x].cnt0;}else{init(lch , l , mid);init(rch , mid + 1 , r);Tree[x] = pushup(Tree[lch] , Tree[rch]);}}void modify(int x , int l , int r , int tar){if(l == r){Tree[x].l ^= 1; Tree[x].r ^= 1;Tree[x].cnt0 ^= 1; Tree[x].sum ^= 1; Tree[x].cnt1 ^= 1;Tree[x].lft[1][0] ^= 1; Tree[x].rht[1][0] ^= 1; Tree[x].lft1[1] ^= 1; Tree[x].rht1[1] ^= 1;Tree[x].lft[0][1] ^= 1; Tree[x].rht[0][1] ^= 1; Tree[x].lft1[0] ^= 1; Tree[x].rht1[0] ^= 1;return;}if(mid >= tar) modify(lch , l , mid , tar);else modify(rch , mid + 1 , r , tar);Tree[x] = pushup(Tree[lch] , Tree[rch]);}node query(int x , int l , int r , int L , int R){if(l >= L && r <= R) return Tree[x];bool f = mid >= L; node t;if(f) t = query(lch , l , mid , L , R);if(mid < R) t = f ? pushup(t , query(rch , mid + 1 , r , L , R)) : query(rch , mid + 1 , r , L , R);return t;}
}
using segTree::init; using segTree::modify; using segTree::query;signed main(){#ifndef ONLINE_JUDGEfreopen("in","r",stdin);//freopen("out","w",stdout);#endifN = read();init(1 , 1 , N);for(int M = read() ; M ; --M)if(read() == 2){int l = read() , r = read();cout << (r - l + 1) * (r - l + 2) / 2 - query(1 , 1 , N , l , r).sum << endl;}else modify(1 , 1 , N , read());return 0;
}

转载于:https://www.cnblogs.com/Itst/p/10498675.html

BZOJ5294 BJOI2018 二进制 线段树相关推荐

  1. 中国石油大学(华东)暑期集训--二进制(BZOJ5294)【线段树】

    问题 C: 二进制 时间限制: 1 Sec  内存限制: 128 MB 提交: 8  解决: 2 [提交] [状态] [讨论版] [命题人:] 题目描述 pupil发现对于一个十进制数,无论怎么将其的 ...

  2. Codeforces Round #807 (Div. 2) E. Mark and Professor Koro 二进制/线段树

    题目分析 模拟题目不难发现,实际上擦除操作就是在模拟二进制加法进位.那么可以得到原题意的转述: 将每个 a [ i ] a[i] a[i]看作 2 a [ i ] 2^{a[i]} 2a[i],维护整 ...

  3. 【BZOJ3821/UOJ46】玄学(二进制分组,线段树)

    [BZOJ3821/UOJ46]玄学(二进制分组,线段树) 题面 BZOJ UOJ 题解 呜,很好的题目啊QwQ. 离线做法大概可以线段树分治,或者直接点记录左右两次操作时的结果,两个除一下就可以直接 ...

  4. Multidimensional Queries(二进制枚举+线段树+Educational Codeforces Round 56 (Rated for Div. 2))...

    题目链接: https://codeforces.com/contest/1093/problem/G 题目: 题意: 在k维空间中有n个点,每次给你两种操作,一种是将某一个点的坐标改为另一个坐标,一 ...

  5. 皮卡丘的梦想2(线段树+二进制状态压缩)

    Description 一天,一只住在 501 实验室的皮卡丘决定发奋学习,成为像 LeiQ 一样的巨巨,于是他向镇上的贤者金桔请教如何才能进化成一只雷丘. 金桔告诉他需要进化石才能进化,并给了他一个 ...

  6. New Year Tree(dfs序+线段树+二进制)

    题意: 给出一棵 n个节点的树,根节点为 1.每个节点上有一种颜色 ci.m次操作.操作有两种: 1 u c:将以 u为根的子树上的所有节点的颜色改为c. 2 u:询问以 u为根的子树上的所有节点的颜 ...

  7. 【线段树】二进制(luogu 4428)

    正题 luogu 4428 题目大意 给你一个01串,让你进行一下两种操作: 1.将其中一位取反 2.问你某一段中有多少个子串满足有一种排列方案,使得组成的二进制数是3的倍数 解题思路 不难发现,因为 ...

  8. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

  9. 2017年ICPC西安邀请赛A、XOR(线段树套线性基 + 思维)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目传送门 Problem 给你 nnn 和 nnn 个整数的数组 aaa,以及kkk和qqq,有 q ...

  10. 2018.06.28 与或(线段树)

    #与或 描述 样例输入 5 8 1 3 2 5 4 3 1 3 2 1 1 5 3 1 3 1 1 4 6 2 3 4 1 3 2 3 2 2 3 4 3 1 5 **样例输出 ** 3 5 3 7 ...

最新文章

  1. Pytorch | BERT模型实现,提供转换脚本【横扫NLP】
  2. 到底这个电路是如何振荡的?
  3. servlet输出html
  4. 借助联合体union的特性实现检测当前计算机环境采用的是大端模式还是小端模式
  5. 深入学习微框架:Spring Boot
  6. 在windows下安装flex和bison、GCC
  7. wxWidgets:wxConfig 概述
  8. python面向对象抽象
  9. 网络研讨室_即将举行的网络研讨会:调试生产中Java的5种最佳实践
  10. NS3可视化问题及解决办法
  11. java socket android_Android:这是一份很详细的Socket使用攻略
  12. 使用Maven命令安装jar包到repo中
  13. 苹果出现长方形透明框_安卓还像苹果用户所说用两年就卡吗?|安卓|安卓系统|安卓手机|苹果ios...
  14. arcgis 发布服务
  15. 银河麒麟服务器操作系统 V10 SP1 安装教程
  16. “80后”!顶尖985,迎新副校长!
  17. 关于‘\0’ ,‘0’, “0” ,0的理解
  18. Windows命令实现匿名邮件发送
  19. java培训机构靠谱吗,已入坑老司机给你的几点忠告
  20. java程序设计案例_Java程序设计案例教程

热门文章

  1. shell编程之awk(数据筛选与处理)
  2. 看完这篇,轻松解决FastReport合并单元格!
  3. 【转】PV3D的小练习~太阳系八大行星
  4. html页面添加动态动画小人,博客页面添加动态小人
  5. Html5中鼠标经过图片,图片在盒子内部实现放大效果。
  6. magicbook屏幕_荣誉Magicbook 15降压笔记本电脑的最佳爆炸现在
  7. 简历学习课程:1-9课
  8. 坚持定投3年,我赚了多少钱?
  9. (译)《科学美国人》:多样的人际网络导致繁荣的本地经济
  10. Unity简单爆炸效果的实现