HDU 4391 Paint The Wall(分块+延迟标记)
Paint The Wall
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3427 Accepted Submission(s): 955
Xenocide spends all day in front of the wall. Sometimes, he paints some consecutive nodes so that these nodes have the same color. When he feels tired, he focuses on a particular color and counts the number of nodes that have this color within a given interval.
Now Xenocide is tired of counting, so he turns to you for help.
The first line of each test case contains two integer n, m(1<=n, m<=100000) indicating the length of the wall and the number of queries.
The following line contains N integers which describe the original color of every position.
Then m lines follow. Each line contains 4 non-negative integers a, l, r, z(1<=a<=2, 0<=l<=r<n ,0<=z<231).
a = 1 indicates that Xenocide paints nodes between l and r and the resulting color is z.
a = 2 indicates that Xenocide wants to know how many nodes between l and r have the color z.
题目链接:HDU 4391
一开始一看以为是线段树,虽然这题有很多人线段树+剪枝过的,如果用的是区间最大值最小值剪枝,粗略一想确实剪枝挺强,它用了一种二分的思想——区间大小跟最大值最小值之差肯定是存在单调不减的关系,但是对于特殊数据就没戏了,比如151515151515,然后查询1,n,3,这样一来3确实一直在1~5之间,但是会一直递归到根节点,最后却连发现一个3都没有,因此这题正解之一应该是分块算法,每一个块维护这个块所控制区间的颜色及每一个颜色的数量信息,此处有分块的区间更新操作,因此需要lazy的思想,跟线段树一样,整块打标记,标记传递时把信息传递到真实数组里去,学习一个分块下的延迟标记的用法,最后注意一下题目中的数组都是从0开始的
代码:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 100010;
const int M = sqrt(N) + 10;
struct block
{
int color, l, r;
map<int, int>info;
inline int len()
{
return r - l + 1;
}
};
block B[M];
int arr[N], belong[N];
int unit, bcnt; void init(int n)
{
unit = sqrt(n);
bcnt = n / unit;
if (n % unit)
++bcnt;
for (int i = 1; i <= bcnt; ++i)
{
B[i].l = (i - 1) * unit + 1;
B[i].r = i * unit;
B[i].color = -1;
B[i].info.clear();
}
B[bcnt].r = n;
for (int i = 1; i <= n; ++i)
{
belong[i] = (i - 1) / unit + 1;
++B[belong[i]].info[arr[i]];
}
}
void pushdown(int x)
{
if (~B[x].color)
{
for (int i = B[x].l; i <= B[x].r; ++i)
arr[i] = B[x].color;
B[x].info.clear();
B[x].info[B[x].color] = B[x].len();
B[x].color = -1;
}
}
void update(int l, int r, int c)
{
int bl = belong[l], br = belong[r];
for (int i = bl + 1; i < br; ++i)
B[i].color = c;
if (bl != br)
{
pushdown(bl);
pushdown(br);
for (int i = l; i <= B[bl].r; ++i)
{
--B[bl].info[arr[i]];
++B[bl].info[c];
arr[i] = c;
}
for (int i = B[br].l; i <= r; ++i)
{
--B[br].info[arr[i]];
++B[br].info[c];
arr[i] = c;
}
}
else
{
pushdown(bl);
for (int i = l; i <= r; ++i)
{
--B[bl].info[arr[i]];
++B[bl].info[c];
arr[i] = c;
}
}
}
int query(int l, int r, int c)
{
int ret = 0;
int bl = belong[l], br = belong[r];
for (int i = bl + 1; i < br; ++i) //先处理中间
{
if (~B[i].color)
ret += B[i].len() * (B[i].color == c);
else
{
if (B[i].info.find(c) != B[i].info.end())
ret += B[i].info[c];
}
}
if (bl == br)
{
pushdown(bl);
for (int i = l; i <= r; ++i)
ret += (arr[i] == c);
}
else
{
pushdown(bl);
pushdown(br);
for (int i = l; i <= B[bl].r; ++i)
ret += (arr[i] == c);
for (int i = B[br].l; i <= r; ++i)
ret += (arr[i] == c);
}
return ret;
}
int main(void)
{
int n, m, a, l, r, z, i;
while (~scanf("%d%d", &n, &m))
{
for (i = 1; i <= n; ++i)
scanf("%d", &arr[i]);
init(n);
while (m--)
{
scanf("%d%d%d%d", &a, &l, &r, &z);
++l, ++r;
if (a == 1)
update(l, r, z);
else
printf("%d\n", query(l, r, z));
}
}
return 0;
}
HDU 4391 Paint The Wall(分块+延迟标记)的更多相关文章
- HDU 4391 - Paint The Wall - 分块哈希入门
题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=4391 题意 : 给一段区间, 有两种操作 1 : 给 x 到 y 的区间染色为 z 2 : 查询 ...
- HDU 4391 Paint The Wall(分块的区间维护)
题意:给出几个操作,把l-r赋值为z,询问l-r有几个z,其中z < INT_MAX 思路:因为z很大,所以很难直接用线段树去维护.这里可以使用分块来解决.我们可以让每个块用map去储存map[ ...
- HDU 4391 Paint The Wall 段树(水
意甲冠军: 特定n多头排列.m操作 以下是各点的颜色 以下m一种操纵: 1 l r col 染色 2 l r col 问间隔col色点 == 通的操作+区间内最大最小颜色数的优化,感觉非常不科学... ...
- NBUT校赛 J Alex’s Foolish Function(分块+延迟标记)
Problem J: Alex’s Foolish Function Time Limit: 8 Sec Memory Limit: 128 MB Submit: 18 Solved: 2 Des ...
- hdu 1543 Paint the Wall
http://acm.hdu.edu.cn/showproblem.php?pid=1543 #include <cstdio> #include <cstring> #inc ...
- 线段树 扫描线 L - Atlantis HDU - 1542 M - City Horizon POJ - 3277 N - Paint the Wall HDU - 1543
学习博客推荐——线段树+扫描线(有关扫描线的理解) 我觉得要注意的几点 1 我的模板线段树的叶子节点存的都是 x[L]~x[L+1] 2 如果没有必要这个lazy 标志是可以不下传的 也就省了一个pu ...
- 杭电 HDU ACM 1698 Just a Hook(线段树 区间更新 延迟标记)
欢迎"热爱编程"的高考少年--报考杭州电子科技大学计算机学院 Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memor ...
- HDU 5785 Interesting manacher + 延迟标记
题意:给你一个串,若里面有两个相邻的没有交集的回文串的话,设为S[i...j] 和 S[j+1...k],对答案的贡献是i*k,就是左端点的值乘上右端点的值. 首先,如果s[x1....j].s[x2 ...
- HDU 3468:A Simple Problem with Integers(线段树+延迟标记)
A Simple Problem with Integers Case Time Limit: 2000MS Description You have N integers, A1, A2, ... ...
随机推荐
- 【洛谷1337】[JSOI2004] 吊打XXX(模拟退火经典题)
点此看题面 大致题意: 一个平面上有\(n\)个点,每个点有1个权值,现在要选择平面上的一个点,使这\(n\)个点的权值乘上到达选定点的距离之和最小. 模拟退火 我们可以用模拟退火来做这道题. 先将\ ...
- node基础
javascript window gulp ---- 前端工程构建工具 webpack ---- 前端工程构建工具 java Python php:后台 本地电脑,服务器 node 本地或服务端运行 ...
- Android驱动开发5-7总结
Android深度探索5-7章总结 介绍了S3C6410开发板的功能,开发板的不同主要是在烧录嵌入式系统的方式不同,以及如何在此开发板上安装Android.紧接着学到介绍到如何在多种平台,使用多种方式 ...
- c++异常处理--创建自己的异常处理类
复习了一下c++中的异常处理! 继承exception类 class myException : public std::exception { public: explicit myExceptio ...
- 【Django】Django开发中的日志输出
开发环境:Ubuntu16.04+Django 1.11.9+Python2.7 一:使用自定义函数输出日志到log文件: import time def print_log(log): file_o ...
- Django之视图和URL配置
1.在创建项目时,Django会自动创建URL配置,在urls.py文件中 文件的默认内容如下所示: """mysite URL Configuration The ur ...
- inotifywait实时监控文件目录
一.inotify简介 inotify 是一种强大的.细粒度的.异步文件系统监控机制,它满足各种各样的文件监控需要,可以监控文件系统的访问属性.读写属性.权限属性.创建删除.移动等操作,也可以监控文件 ...
- setInterval与setTimeout
在自己用canvas画一个时钟时,画秒钟用的是利用图片将重复的线条遮住,但是会出现有两个秒钟线条同时存在,才想起setInterval有那么个坑,查了点资料,记录下,若有不对的或者未写到的点,还请大家 ...
- Python知识点进阶——迭代器
可迭代对象 可迭代对象可以简单的理解为用for循环遍历的,如list.tuple.dict.set.str 判断一个对象是否是迭代器: 可以将数据类型 和 是否为可迭代对象 比较来判断是否是可以迭代 ...
- Java流(Stream)、文件(File)和IO
Java.io包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io包中的流支持很多格式,比如:基本类型.对象.本地化字符集等等. 一个流可以理解为一个数据的序列 ...