题意:给出几个操作,把l-r赋值为z,询问l-r有几个z,其中z < INT_MAX

思路:因为z很大,所以很难直接用线段树去维护。这里可以使用分块来解决。我们可以让每个块用map去储存map[i]的个数,用类似线段树的lazy标记来给整个块更新,当需要对块内某些数操作时再pushdown。

注意一下不要随意开辟map的空间,在计算区间的z的个数时应采用

if(b[i].num.find(z) != b[i].num.end()) ans += b[i].num[z];

减少空间开辟。

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
struct Block{
map<int, int> num;
int lazy, L, R;
}b[];
int belong[maxn], a[maxn], block, sz;
int n, m;
void init(){
block = sqrt(n * 1.0);
for(int i = ; i < n; i++)
belong[i] = i / block + ;
sz = belong[n - ];
for(int i = ; i <= sz; i++){
b[i].lazy = -;
b[i].L = (i - ) * block;
b[i].R = min(b[i].L + block - , n - );
b[i].num.clear();
for(int j = b[i].L; j <= b[i].R; j++){
b[i].num[a[j]]++;
}
}
}
void push_down(int x){
b[x].num.clear();
for(int i = b[x].L; i <= b[x].R; i++)
a[i] = b[x].lazy;
b[x].num[b[x].lazy] = b[x].R - b[x].L + ;
b[x].lazy = -;
}
void update(int ll, int rr, int z){
int l = belong[ll], r = belong[rr];
int L, R;
if(l == r){
if(b[l].lazy != -) push_down(l);
for(int i = ll; i <= rr; i++){
b[l].num[a[i]]--;
b[l].num[z]++;
a[i] = z;
}
}
else{
L = ll, R = b[l].R;
if(b[l].lazy != -) push_down(l);
for(int i = L; i <= R; i++){
b[l].num[a[i]]--;
b[l].num[z]++;
a[i] = z;
} L = l + , R = r - ;
for(int i = L; i <= R; i++)
b[i].lazy = z; L = b[r].L, R = rr;
if(b[r].lazy != -) push_down(r);
for(int i = L; i <= R; i++){
b[r].num[a[i]]--;
b[r].num[z]++;
a[i] = z;
}
}
}
int query(int ll, int rr, int z){
int l = belong[ll], r = belong[rr];
int L, R, ans = ; if(l == r){
if(b[l].lazy != -) push_down(l);
for(int i = ll; i <= rr; i++){
if(a[i] == z) ans++;
}
return ans;
}
else{
L = ll, R = b[l].R;
if(b[l].lazy != -) push_down(l);
for(int i = L; i <= R; i++){
if(a[i] == z) ans++;
} L = l + , R = r - ;
for(int i = L; i <= R; i++){
if(b[i].lazy != -){
if(b[i].lazy == z) ans += b[i].R - b[i].L + ;
}
else{
if(b[i].num.find(z) != b[i].num.end()) ans += b[i].num[z]; //不开辟新空间
}
} L = b[r].L, R = rr;
if(b[r].lazy != -) push_down(r);
for(int i = L; i <= R; i++){
if(a[i] == z) ans++;
}
return ans;
}
}
int main(){
while(~scanf("%d%d", &n, &m)){
for(int i = ; i < n; i++){
scanf("%d", &a[i]);
}
init();
while(m--){
int o, l, r, z;
scanf("%d%d%d%d", &o, &l, &r, &z);
if(o == ){
update(l, r, z);
}
else{
printf("%d\n", query(l, r, z));
}
}
}
return ;
}

HDU 4391 Paint The Wall(分块的区间维护)的更多相关文章

  1. HDU 4391 - Paint The Wall - 分块哈希入门

    题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=4391 题意 : 给一段区间, 有两种操作 1 : 给 x 到 y 的区间染色为 z 2 : 查询 ...

  2. HDU 4391 Paint The Wall(分块+延迟标记)

    Paint The Wall Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. HDU 4391 Paint The Wall 段树(水

    意甲冠军: 特定n多头排列.m操作 以下是各点的颜色 以下m一种操纵: 1 l r col 染色 2 l r col 问间隔col色点 == 通的操作+区间内最大最小颜色数的优化,感觉非常不科学... ...

  4. hdu 1556 Color the ball(线段树区间维护+单点求值)

    传送门:Color the ball Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/3276 ...

  5. hdu 1543 Paint the Wall

    http://acm.hdu.edu.cn/showproblem.php?pid=1543 #include <cstdio> #include <cstring> #inc ...

  6. HDU 6315 Naive Operations(线段树+区间维护)多校题解

    题意:a数组初始全为0,b数组题目给你,有两种操作: 思路:dls的思路很妙啊,我们可以将a初始化为b,加一操作改为减一,然后我们维护一个最小值,一旦最小值为0,说明至少有一个ai > bi,那 ...

  7. 线段树 扫描线 L - Atlantis HDU - 1542 M - City Horizon POJ - 3277 N - Paint the Wall HDU - 1543

    学习博客推荐——线段树+扫描线(有关扫描线的理解) 我觉得要注意的几点 1 我的模板线段树的叶子节点存的都是 x[L]~x[L+1] 2 如果没有必要这个lazy 标志是可以不下传的 也就省了一个pu ...

  8. HDU 4012 Paint on a Wall(状压+bfs)

    Paint on a Wall Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) ...

  9. hdu 3669 Cross the Wall(斜率优化DP)

    题目连接:hdu 3669 Cross the Wall 题意: 现在有一面无限大的墙,现在有n个人,每个人都能看成一个矩形,宽是w,高是h,现在这n个人要通过这面墙,现在只能让你挖k个洞,每个洞不能 ...

随机推荐

  1. Unity shader学习之遮罩纹理

    什么是遮罩? 遮罩允许我们可以保护某些区域,使它们奂于某些修改. 例如下面的例子,使用遮罩来控制高光反射. 转载请注明出处:http://www.cnblogs.com/jietian331/p/71 ...

  2. 5.无监督学习-DBSCAN聚类算法及应用

    DBSCAN方法及应用 1.DBSCAN密度聚类简介 DBSCAN 算法是一种基于密度的聚类算法: 1.聚类的时候不需要预先指定簇的个数 2.最终的簇的个数不确定DBSCAN算法将数据点分为三类: 1 ...

  3. zookeeper日志清理

    环境 Red Hat Enterprise Linux Server release 7.3 (Maipo) jdk1.7.0_80      zookeeper-3.4.11 一.事务日志和快照日志 ...

  4. redis和mongodb的比较

    >>RedisRedis的优点:支持多种数据结构,如 string(字符串). list(双向链表).dict(hash表).set(集合).zset(排序set).hyperloglog ...

  5. easyui dialog 和 dategrid相关设置与应用

    1 dialog一些参数   可以进行文件上传等操作closed:true:定义初始状态为关闭:modal:true:对话框被打开时,会有一个modal-mask,使得对话框底部的内容被一个层覆盖,不 ...

  6. ui-router .state参数配置

    .state('页面被引用时的变量名',{ template: '<h1>My Contacts</h1>',//被应用时插入的模板,状态被激活时,它的模板会自动插入到父状态对 ...

  7. 使用json对象要注意的地方

    本人是初学渣渣,使用json过程中遇到常见的问题,总结如下: 1--json对象内部不要有注释,虽然不报错,但是会使得渲染界面失败: 2--json对象是没有length属性的,若想获取到这个leng ...

  8. Spring框架之使用JdbcTemplate开发Dao层程序

    简介: JdbcTemplate开发dao层程序     由Spring框架给我们提供,Spring提供的很多操作数据源(关系型数据库,二维表格模型,有明确的行和列(mysql/orcal等) 非关系 ...

  9. kivy 滑动

    from kivy.uix.gridlayout import GridLayout from kivy.app import App from kivy.lang.builder import Bu ...

  10. MSVCR120.dll 解决

    https://www.microsoft.com/en-us/download/details.aspx?id=40784 装之 from : https://answers.microsoft.c ...