P5057 [CQOI2006]简单题

题目描述

有一个 n 个元素的数组,每个元素初始均为 0。有 m 条指令,要么让其中一段连续序列数字反转——0 变 1,1 变 0(操作 1),要么询问某个元素的值(操作 2)。 例如当 n = 20 时,10 条指令如下:

输入格式

第一行包含两个整数 n, m,表示数组的长度和指令的条数; 以下 m 行,每行的第一个数 t 表示操作的种类:

若 t = 1,则接下来有两个数 L, R,表示区间 [L, R] 的每个数均反转; 若 t = 2,则接下来只有一个数 i,表示询问的下标。

输出格式

每个操作 2 输出一行(非 0 即 1),表示每次操作 2 的回答。

输入输出样例

输入 #1

20 10

1 1 10

2 6

2 12

1 5 12

2 6

2 15

1 6 16

1 11 17

2 12

2 6

输出 #1

1

0

0

0

1

1

说明/提示

对于 50% 的数据,\(1 ≤ n ≤ 10^3\),$ 1 ≤ m ≤ 10^4$; 对于 100% 的数据,\(1 ≤ n ≤ 10^5\), \(1 ≤ m ≤ 5 × 10^5\),保证 L ≤ R。

【树状数组】

【思路】

树状数组

【题目大意】

区间反转和单点询问

【题目分析】

区间反转我首先想到了是线段树

用lazy标记某个区间反转过几次

但是我是抱着练习树状数组的目的

来做的这道题

所以必须用树状数组做!!!

不过树状数组该怎么办呢?

难不成枚举每一个点然后修改?

不对

这个时候情不自禁想到了那个优美的东西

差分

类似树状数组模板2的方法

差分一下下就可以很轻松标记翻转次数了

【核心思路】

树状数组维护差分数组

差分数组修改区间

只需要在区间左端点加上修改的值

在右端点之后减去修改的值就好了

求某个位置上的值

就是这个位置之前(包括这个位置)的和

也符合树状数组里面的sum

就不需要做差了

最后按照%2来输出就好了

因为翻转两次之后会回到原来的情况

【思路】

#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
const int Max = 100006;
int a[Max];
int n,m;
int read()
{
int sum = 0,fg = 1;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-')fg = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
sum = sum * 10 + c - '0';
c = getchar();
}
return sum * fg;
} int lowbit(int x)
{
return x & -x;
} void add(int x,int y)
{
while(x <= n)
{
a[x] += y;
x += lowbit(x);
}
} int sum(int x)
{
int ans = 0;
while(x > 0)
{
ans += a[x];
x -= lowbit(x);
}
return ans;
} signed main()
{
n = read(),m = read();
for(register int i = 1;i <= m;++ i)
{
int t = read();
if(t == 1)
{
int l = read(),r = read();
add(l,1);
add(r + 1,-1);
}
else
{
int qwq = read();
cout << sum(qwq) % 2 << endl;
}
}
return 0;
}

【线段树】

【思路】

线段树

首先感谢@大魔鬼灿灿 巨佬帮我滑鼠标

用树状数组做过了,但是还是可以用线段树做的

所以也拿线段树来做回顾一下线段树,

然后没想到调试了两个小时

【核心思路】

sum记录这个点被修改的次数

因为是区间修改和单点查询

所以线段树中只要不是叶子节点的sum就不需要求了

只用来lazy标记就可以了

然后该下放到叶子节点的时候就下发好了

最后输出记录的修改次数%2

【注意事项】

不管不是叶子节点的sum没问题

但是有的修改的时候却是单点修改

所以该sum++还是得sum++的

把全部节点的sum都当叶子节点的来处理

加上修改的次数

也就是lazy值就好了

【完整代码】

#include<iostream>
#include<cstdio>
#define lson (k << 1)
#define rson (k << 1 | 1) using namespace std; int read()
{
int sum = 0,fg = 1;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-')fg = -1;c = getchar();}
while(c >= '0' && c <= '9'){sum = sum * 10 + c - '0';c = getchar();}
return sum * fg;
}
const int Max = 100004;
struct node
{
int l,r;
int lazy;
int sum;
}a[Max << 2];
int n,m;
int opx,opl,opr; void build(int k,int l,int r)
{
a[k].l = l;a[k].r = r;
if(l == r)
return;
int mid = (l + r) >> 1;
build(lson,l,mid);
build(rson,mid + 1,r);
return;
} void down(int k)
{
if(a[k].lazy)
{
a[lson].sum += a[k].lazy;
a[rson].sum += a[k].lazy;
a[lson].lazy += a[k].lazy;
a[rson].lazy += a[k].lazy;
a[k].lazy = 0;
}
} void change(int k)
{
if(opl <= a[k].l && opr >= a[k].r)
{
a[k].lazy ++;
a[k].sum++;
return;
}
down(k);
int mid = (a[k].l + a[k].r) >> 1;
if(opl <= mid)change(lson);
if(opr > mid)change(rson);
a[k].sum = a[lson].sum + a[rson].sum;
} void query(int k)
{
if(a[k].l == opx && a[k].r == opx)
{
cout << a[k].sum % 2 << endl;
return;
}
down(k);
int mid = (a[k].l + a[k].r) >> 1;
if(opx <= mid) query(lson);
if(opx > mid) query(rson);
} int main()
{
n = read(),m = read();
build(1,1,n);
for(register int i = 1;i <= m;++ i)
{
int qwq = read();
if(qwq == 1)
{
opl = read(),opr = read();
change(1);
}
else
{
opx = read();query(1);
}
}
return 0;
}

洛谷 P5057 [CQOI2006]简单题 题解的更多相关文章

  1. 洛谷 P5057 [CQOI2006]简单题 (树状数组,位运算)

    题意:有一个长度为\(n\)的数组,进行\(m\)次操作,每次读入一个值\(t\),如果\(t=1\),则将区间\([l,r]\)的数字反转,若\(t=2\),则查询下标为\(i\)的值. 题解:树状 ...

  2. 洛谷P5057 [CQOI2006]简单题(线段树)

    题意 题目链接 Sol 紫色的线段树板子题??... #include<iostream> #include<cstdio> #include<cmath> usi ...

  3. [洛谷P5057][CQOI2006]简单题

    题目大意:有一个长度为$n$的$01$串,两个操作: $1\;l\;r:$把区间$[l,r]$翻转($0->1,1->0$) $2\;p:$求第$p$位是什么 题解:维护前缀异或和,树状数 ...

  4. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

  5. P5057 [CQOI2006]简单题(线段树)

    果然简单题,5分钟紫题++ 代码 #include <cstdio> #include <algorithm> #include <cstring> using n ...

  6. 洛谷P1072Hankson的趣味题题解

    题目 一道十分经典的数论题,在考场上也可以用暴力的算法来解决,从而得到\(50pts\)的较为可观的分数,而如果想要AC的话,我们观察原题给的数据范围\(a,b,c,d\)(为了好表示,分别代表a1, ...

  7. 【洛谷P4148】简单题(kd-tree)

    传送门 题意: 给出一个\(n*n\)的棋盘,现在有两种操作:一种是某个格子里的数字加上\(A\),另一种是询问矩阵和. 空间限制:\(20MB\),强制在线. 思路: 直接\(kd-tree\)来搞 ...

  8. P5057 [CQOI2006]简单题 前缀异或差分/树状数组

    好思路,好思路... 思路:前缀异或差分 提交:1次 题解:区间修改,单点查询,树状数组,如思路$qwq$ #include<cstdio> #include<iostream> ...

  9. P5057 [CQOI2006]简单题

    题目描述 有一个 n 个元素的数组,每个元素初始均为 0.有 m 条指令,要么让其中一段连续序列数字反转——0 变 1,1 变 0(操作 1),要么询问某个元素的值(操作 2). 例如当 n = 20 ...

随机推荐

  1. PyQt5笔记之菜单栏

    目录 菜单栏 创建单层菜单 创建多层菜单 右键打开菜单 官方菜单实例 菜单常用方法 菜单栏 创建单层菜单 import sys from PyQt5.QtWidgets import QApplica ...

  2. python爬取电影网站信息

    一.爬取前提1)本地安装了mysql数据库 5.6版本2)安装了Python 2.7 二.爬取内容 电影名称.电影简介.电影图片.电影下载链接 三.爬取逻辑1)进入电影网列表页, 针对列表的html内 ...

  3. 19条常用的MySQL优化方法(转)

    本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下:1.EXPLAIN命令做MySQL优化,我们要善用EXPLAIN查看SQL执行计划.下面来个简单的示例,标注(1.2.3.4.5)我们 ...

  4. kubeadm安装kubernetes 1.16.2

    目录 简介 环境说明 安装 准备基础环境 安装docker 安装kubeadm.kubelet.kubectl 配置kubeadm-config.yaml 部署master 安装flannel网络插件 ...

  5. Hbase put写入源码分析

    今天有空闲时间看一下HBASE的写入代码 MutiAction类,是一个action的container,包括get . put. delete.并且是根据region name分组的.其中核心的就是 ...

  6. pytest_demo_实战1

    1.根目录配置 pytest.ini [pytest] addopts = -p no:warnings 2.更改运行手势,系统配置 file -> setting -> Tools -& ...

  7. Centos7利用rsync实现文件同步

    0x01 测试环境 CentOS 7.4 Rsync服务端:192.168.204.130 CentOS 7.4 Rsync客户端:192.168.204.168 0x02 rsync同步方式 第一种 ...

  8. Web应急:网站被植入Webshell

    网站被植入webshell,意味着网站存在可利用的高危漏洞,攻击者通过利用漏洞入侵网站,写入webshell接管网站的控制权.为了得到权限 ,常规的手段如:前后台任意文件上传,远程命令执行,Sql注入 ...

  9. 【docker】centos7 上拉取docker镜像,一直拉取不到,报错:Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while w

    镜像拉取一直报错: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request cancel ...

  10. windows下生成ssl

    1.安装git window 需要安装 git 按部就班即可 https://git-scm.com/ 2.安装完之后,打开 Git Bash 输入以下命令并执行,然后一路按“回车”即可,效果见图: ...