title: ZCMU1156 新年彩灯1(树状数组区间更新单点查询)
date: 2018-07-29 19:00:55
tags: [树状数组,ZCMU,算法]
categories: 算法
新年将至,YY准备挂一排彩灯,已知彩灯刚挂完的彩灯共有N盏(编号为1,2,3,……),并且都是灭的。彩灯的闪烁由一段程序控制。
每一秒钟程序会生成两个正整数a和b(1<=a,b<=N),然后将编号为a和b之间的所有灯的状态改变一次,即如果灯i是灭的,那么经过一次改变,灯i会亮,如果灯i是亮的,经过一次改变,灯i会灭。
当YY看着自己挂的彩灯不断闪烁的时候,问题来了,YY想知道任意时刻某一区间灯的状态。
多组测试数据,每一组第一行是一个整数N(1<=N<=1000000)和一个整数M(1<=M<=3000)。
然后是M行数据,包括以下两种形式:
1 a b 表示灯a和灯b之间的灯(含灯a和灯b)变换一次状态。
0 x y 表示YY想知道此刻灯x到灯y(包含灯x和灯y)的状态.
对于每次YY想知道结果的时候,输出一行灯的状态(编号小的灯优先),如果是亮的输出”1”,否则输出”0”;
3 3
1 1 2
1 2 3
0 1 3
101
一开始以为这是题简单的模拟,所以跟着题目的要求用for循环不停的实现,每次按按钮执行+1,最后要判断时看对应的数是奇数还是偶数就好了。然而这样TLE了。
原来题目没想让我简单模拟,再回过去看到有关键词区间修改,自然想到了用树状数组代替那两个按按钮和判断亮灭的操作。虽题中说要查询某个区间的亮灭情况,但查询亮灭不涉及求和操作,所以这道题本质上还是区间修改,单点查询 。若读者不了解树状数组具体的原理和操作,我将会在另一篇博客给出这些内容。
给出的区间头和尾不一定前大后小,可能会有1 2 1这样的数据,需自行判断并交换
#include<bits/stdc++.h>
using namespace std;
int a[1000005];
int tree[1000005];
int n,m;
void add(int x,int num)
{
for(;x<=n;x+=x&-x)
tree[x]+=num;
}
int sum(int x)
{
int answer =0;
for(;x>0;x-=x&-x)
answer+=tree[x];
return answer;
}
int main()
{
int flag,l,r,t;
while(~scanf("%d %d",&n,&m))
{
memset(tree,0,sizeof(tree));
memset(a,0,sizeof(a));
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&flag,&l,&r);
if(l>r)
{
t=r;r=l;l=t;
}
if(flag==1)
{
add(l,1);
add(r+1,-1);
}
else
{
for(int j=l;j<=r;j++)
{
if(sum(j)%2==1) printf("1");
else printf("0");
}
printf("n");
}
}
}
return 0;
}
相关知识
[HDOJ4325]Flowers(树状数组 离散化)
[HEOI2012] 树状数组 + 离线预处理 超详解【校队排位赛#12 J】
从select查询中将强制转换的值提取到数组中
算法的艺术
数组退化
NYOJ 600 花儿朵朵 树状数组
C++ 程序设计:花期内花的数目(LeetCode:2251)
贪心算法练习
Leetcode 题解
花样月季花色多样 3公分树状月季基地 濮阳月季基地
网址: ZCMU1156 新年彩灯1(树状数组区间更新单点查询) https://m.huajiangbk.com/newsview105208.html
上一篇: 1高等学校校园建筑节能监管系统建 |
下一篇: 上海市工程施工规范.doc |