博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P2574 XOR的艺术
阅读量:5015 次
发布时间:2019-06-12

本文共 2459 字,大约阅读时间需要 8 分钟。

题目来源:

题目描述

AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏。在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下

1、 拥有一个伤害串为长度为n的01串。

2、 给定一个范围[l,r],伤害为伤害串的这个范围内中1的个数

3、 会被随机修改伤害串中的数值,修改的方法是把[l,r]中的所有数xor上1

AKN想知道一些时刻的伤害,请你帮助他求出这个伤害

输入输出格式

输入格式:

 

第一行两个数n,m,表示长度为n的01串,有m个时刻

第二行一个长度为n的01串,为初始伤害串

第三行开始m行,每行三个数p,l,r

若p为0,则表示当前时刻改变[l,r]的伤害串,改变规则如上

若p为1,则表示当前时刻AKN想知道[l,r]的伤害

 

输出格式:

 

对于每次询问伤害,输出一个数值伤害,每次询问输出一行

 

输入输出样例

输入样例#1: 
10 610111010010 2 41 1 50 3 71 1 100 1 41 2 6
输出样例#1: 
361

说明

样例解释:

1011101001

1100101001

询问[1,5]输出3

1111010001

询问[1,10]输出6

0000010001

询问[2,6]输出1

数据范围:

10%数据2≤n,m≤10

另有30%数据2≤n,m≤2000

100%数据2≤n,m≤2*10^5

By:worcher

 

解析:

水题快乐!

这道题的关键在lazytag的处理上。

我们不难发现01数列区间所有数值对1异或的规律:

给出一条长为n的01数列,若其1的数量为k,则其对1异或后的1的数量为为n-k;

例如:一条长为10的01数列:1011101001,1的数量为6,其对1111111111异或后得到数列:0100010110,1的数量为4;

得到如下pushdown操作:

1 t[p<<1].att=(t[p<<1].r-t[p<<1].l+1)-t[p<<1].att;2 t[(p<<1)|1].att=(t[(p<<1)|1].r-t[(p<<1)|1].l+1)-t[(p<<1)|1].att;

其他的还是差不多。

参考代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f#define PI acos(-1.0)#define N 200010#define MOD 2520#define E 1e-12using namespace std;struct segmentree{ int l,r; int att; bool flag;}t[N*4];void spread(int p){ if(t[p].flag) { t[p<<1].flag^=1; t[(p<<1)|1].flag^=1; t[p<<1].att=(t[p<<1].r-t[p<<1].l+1)-t[p<<1].att; t[(p<<1)|1].att=(t[(p<<1)|1].r-t[(p<<1)|1].l+1)-t[(p<<1)|1].att; t[p].flag=0; }}void built(int p,int l,int r){ t[p].l=l;t[p].r=r; if(l==r){ scanf("%1d",&t[p].att);//当然也可以使用字符串读入,且速度更快,不过这个读入比较冷门且写法简单 return; } int mid=(l+r)>>1; built(p<<1,l,mid); built((p<<1)|1,mid+1,r); t[p].att=t[p<<1].att+t[(p<<1)|1].att;}void change(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r){ t[p].att=(t[p].r-t[p].l+1)-t[p].att; t[p].flag^=1;//注意这里必须是^1,才能保证延迟标记的准确性 return; } spread(p); int mid=(t[p].l+t[p].r)>>1; if(l<=mid) change(p<<1,l,r); if(r>mid) change((p<<1)|1,l,r); t[p].att=t[p<<1].att+t[(p<<1)|1].att;}int ask(int p,int l,int r){ if(l<=t[p].l&&t[p].r<=r) return t[p].att; spread(p); int mid=(t[p].l+t[p].r)>>1; int val=0; if(l<=mid) val+=ask(p<<1,l,r); if(r>mid) val+=ask((p<<1)|1,l,r); return val;}int main(){ int n,m,flag; scanf("%d%d",&n,&m); built(1,1,n); int l,r; while(m--) { scanf("%d",&flag); scanf("%d%d",&l,&r); if(flag==0) change(1,l,r); else{ printf("%d\n",ask(1,l,r)); } } return 0;}

2019-05-13 18:32:10

 

转载于:https://www.cnblogs.com/DarkValkyrie/p/10858285.html

你可能感兴趣的文章
ODAC(V9.5.15) 学习笔记(三)TOraSession(2)
查看>>
单纯形法
查看>>
SQL中的replace函数
查看>>
java中的类型安全问题-Type safety: Unchecked cast from Object to ...
查看>>
如何解决最后一个尾注引用显示与致谢混为一谈的问题-下
查看>>
Java Socket编程 - 基于TCP方式的二进制文件传输【转】http://blog.csdn.net/jia20003/article/details/8248221...
查看>>
阅读之https及加密原理
查看>>
HDOJ4550 卡片游戏 随便销毁内存的代价就是wa//string类的一些用法
查看>>
css文本样式text、字体样式font
查看>>
python判断图片是否损坏
查看>>
MySQL服务启动:某些服务在未由其他服务或程序使用时将自动停止
查看>>
软件工程第四周作业 - 单元测试
查看>>
KNN与SVM对比&SVM与逻辑回归的对比
查看>>
php 现在拓展地址
查看>>
【Java并发编程】之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码)...
查看>>
团队个人冲刺第三天
查看>>
unit
查看>>
2017-10-17 NOIP模拟赛2
查看>>
How to install ia32-libs in Ubuntu 14.04 LTS (Trusty Tahr)
查看>>
ACM/ICPC 之 模拟 (HNUOJ 13391-换瓶模拟)
查看>>