还有这种操作

ttt 最近在学习二进制, 他想知道小于等于N的数中有多少个数的二进制表示中有偶数个1。

但是他想了想觉得不够dark,于是他增加了若干次操作,每次操作会将一个区间内的0变1 , 1变0,

现在在每次操作之后,他都想知道原来的那个问题的答案。

输入格式:

第一行:一个01序列表示N的二进制表示 
第二行:操作次数 m 
接下来的m行每行两个数,表示要操作的区间。

输出格式:

输出m+1行,第一行表示初始的答案,第二行到第m+1行输出每次操作后的答案 
答案对1e9 + 7 取模

样例输入:

0
1
1 1

样例输出:

1
1

数据范围:

设 n为 N 的 位数

  • 10%, n <= 20, m <= 100
  • 30%, n <= 60, m <= 10000
  • 60%, n <= 1000, m <= 10000
  • 100%, n <= 1000000, m <= 100000

解题思路:

在看到n<=2^1000000时,我的内心是震惊的,想着或者是字典树,线段树

于是想着线段树方向想,但是怎么统计答案又成为了一个问题...

加之题目并没有说l<=r,于是这道题就愉快的爆零了

***下面是正题

我们想用一个线段树,维护每一位的翻转次数,以及每一位的答案的值

那么我们就可以用nlogn的时间建出它,并用mlogn的时间来查询。

好线段树部分讲完了

***下面是关于统计答案的

我们首先可以发现

[0,1)内有2^0=1个

[0,10)内有2^0=1个

[0,100)内有2^1=2个

[0,1000)内有2^2=4个(以上数均为二进制表示)

...

那么我们可以总结了,[0,100..00(n个0))内有2^(n-1)个数满足,此时n>=1(为什么下面会讲)

但是知道这个有什么用么?

我们想一个 1010=1000+10

答案就为[0,1000)+[0,10)+check(1010是否满足)

这个结论的证明留给读者去完成

***于是这个程序基本就成型了

注意:(1)l是可能大于r的

(2)在对于最后一位处理,需要特殊处理,否则,对于最后一位是1的数,会出现1的差别,

例如:101 如按原先方法计算,答案为2+1+check(101)=4,而正确答案是3

因此在遇到原串符合条件,且最后一位是1时,要对答案减一

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=5e6+10,p=1e9+7;
 4 struct xint {int l,r;}a[N];
 5 int val[N],sum[N],pw[N],bo[N],n[N],m,l,r;
 6 char s[N]; bool flag;
 7 void pushup(int rt,int len){
 8     val[rt]=(1ll*val[rt<<1]*pw[len]+val[rt<<1|1])%p;
 9     sum[rt]=sum[rt<<1]^sum[rt<<1|1];
10 }
11 void opera(int rt){
12     bo[rt]^=1; val[rt]=((pw[a[rt].r-a[rt].l+1]-1-val[rt])%p+p)%p;
13     sum[rt]=((a[rt].r-a[rt].l+1)&1)^sum[rt];
14 }
15 void pushdown(int rt){
16     if (bo[rt]) opera(rt*2),opera(rt*2+1),bo[rt]=0;
17 }
18 //--------------------------------
19 void build(int l,int r,int rt){
20     if (l>r) return; a[rt].l=l; a[rt].r=r;
21     if (l==r){
22         val[rt]=sum[rt]=n[l]; return;
23     }
24     int mid=(l+r)>>1;
25     build(l,mid,rt<<1); build(mid+1,r,rt<<1|1);
26     pushup(rt,r-mid);
27 }
28
29 void update(int l,int r,int rt){
30     if (l>r) return;
31     if (a[rt].l==l&&a[rt].r==r){
32         opera(rt); return;
33     }
34     int mid=(a[rt].l+a[rt].r)>>1; pushdown(rt);
35     if(r<=mid) update(l,r,rt<<1);
36         else if (l>mid) update(l,r,rt<<1|1);
37         else update(l,mid,rt<<1),update(mid+1,r,rt<<1|1);
38     pushup(rt,a[rt].r-mid);
39 }
40 int query(){
41     return (val[1]+bool(!sum[1]||flag))%p;
42 }
43 //------------------------------
44 int main(){
45     scanf("%s%d",s+1,&m); int len=strlen(s+1);
46     for (int i=len;i>=1;--i) n[i]=s[i]-'0'; pw[0]=1;
47     for (int i=1;i<=len;++i) pw[i]=pw[i-1]*2%p;
48     build(1,len-1,1); flag=n[len]; printf("%d\n",query());
49     while (m--){
50         scanf("%d%d",&l,&r);
51         if (l>r) swap(l,r);
52         if (r==len) r--,flag^=1;
53         update(l,r,1); printf("%d\n",query());
54     }
55 }

View Code

总结:个人觉得这是一道很好的线段树题目,当然对于我这种蒟蒻,线段树还不能熟练掌握的还要加油

***虽说联赛不考

转载于:https://www.cnblogs.com/logic-yzf/p/7603890.html

[XJOI]noip44 T3还有这种操作相关推荐

  1. 浅析分布式系统之体系结构 - 事务与隔离级别(多对象、多操作)上篇

    事务的本质 数千年前两河流域的楔形文字书写关于贸易.法律.账户等内容的大量文献中就已经提到事务.为了保证整个交易过程中的信息处理(例如:某笔交易)的完整.正确以及可追述,人们需要将各种信息完整正确的记 ...

  2. Oracle Supplemental 补全日志介绍

    转. Oracle补全日志(Supplemental logging)特性因其作用的不同可分为以下几种:最小(Minimal),支持所有字段(all),支持主键(primary key),支持唯一键( ...

  3. 并发场景下MySQL存在的问题及解决思路

    转载自 并发场景下MySQL存在的问题及解决思路 目录 1.背景 2.表锁导致的慢查询的问题 3.线上修改表结构有哪些风险? 4.一个死锁问题的分析 5.锁等待问题的分析 6.小结 一.背景 对于数据 ...

  4. Java JUC工具类--CountDownLatch

    CountDownLatch:用于监听某些初始化操作,并且线程进行阻塞,等初始化执行完毕后,通知主线程继续工作执行 package com.example.core.juc;import java.u ...

  5. C++基础05-类构造函数与析构函数

    总结: 1.类对象的作用域为两个{}之间.在遇到}后开始执行析构函数 2.当没有任何显式的构造函数(无参,有参,拷贝构造)时,默认构造函数才会发挥作用 一旦提供显式的构造函数,默认构造函数不复存在,默 ...

  6. 多线程之CountDownLatch和CyclicBarrier的区别和用法

    一.CountDownLatch的使用 CountDownLatch经常用于监听某些初始化操作,等初始化执行完毕后,再通知主线程继续工作. CountDownLatch定义: 一个同步辅助类,在完成一 ...

  7. oracle删除资产模块凭证,请教老师,固定资产凭证不小心给删除了,然后在固定资产模块那边说已经存在了,那我要怎么做?...

    您好,固定资产在使用过程中,由于特定原因销售出去,会得到出售收入,或者还会发生清理费用.对于清理收入和清理费用只能在卡片管理中显示出来,不能产生凭证传递到总账.对于清理收入和清理费用需要在总账中填制相 ...

  8. oracle 执行sql路径,如何指定 SQL 执行路径

    原标题:如何指定 SQL 执行路径 作者韩涛,来自社区"平台人生"专栏 http://www.talkwithtrend.com/Column/detail/id/11 就像是每个 ...

  9. 【Oracle】闪回技术

    1.闪回技术描述 2.数据库的准备: -undo表空间要设置成AUTO,设置合适的保存时间.undo表空间: SYS@ENMOEDU> show parameter undoNAME TYPE ...

最新文章

  1. 服务器温度3d显示,智能问答助手、3D可视化展示,腾讯医典“黑科技”助力科普更有温度...
  2. Announcing the Updated NGINX and NGINX Plus Plug‑In for New Relic (Version 2)
  3. Keras之ML~P:基于Keras中建立的回归预测的神经网络模型(根据200个数据样本预测新的5+1个样本)——回归预测
  4. arduino控制点阵屏与蜂鸣器_数字制造讲义08-Arduino声音应用2
  5. 垃圾分类毕设java程序_垃圾“拍一拍”,分类不用愁!生活垃圾分类查询小程序上线啦...
  6. Linux下快速设定ip bond
  7. 数据结构与算法-原始版-a+b+c=1000并且a方+b方=c方
  8. 关于git远程版本库的一些问题之解决
  9. akcms在模板文件中书写{php},在模版中灵活处理变量的4种方法
  10. 关于用C#调用C++的dll中的函数,获取字符串返回值的一些细节
  11. 如何使用U盘制作Windows 7安装盘
  12. 牛顿迭代法(求平方根)
  13. Python自动获取邮箱验证码【上集】
  14. Java库:Jansi - 彩色日志输出体验
  15. 伊利洛伊大学厄巴纳-香槟分校计算机专业,伊利诺伊大学香槟分校人工智能系排名必须得慎重来看...
  16. 周鸿祎-- 用户体验和微创新
  17. Linux远程连接服务器
  18. STM32F407控制 无刷直流电机和永磁同步电机
  19. 中英文文献哪里找?七个网站三款软件帮你轻松搞定
  20. 面相对象:赖床运动员,吉尼斯吃不饱记录保持者

热门文章

  1. as5.4安装gcc和g++
  2. IDC商人应不应该给客户提供服务器测试?```
  3. 深入一步研究DNS服务器
  4. C++11新特性(4)
  5. Python检验某个字符(串)是否属于另一个字符串
  6. 1290 the mysql_ERROR 1290:The MySQL server is running with the --secure-file-priv option
  7. python-docx-template 数据渲染_python如何将数据渲染到docx文档指定位置
  8. xNFT Protocol完成天使轮和A轮融资,LD Capital、Fundamental Labs分别领投
  9. 数据:以太坊2.0合约余额新增1.52万ETH
  10. SAP License:ERP项目经理需求调研的惨痛经历