码迷,mamicode.com
首页 > 其他好文 > 详细

【分块】 HDU 4391 Paint The Wall

时间:2015-08-17 13:56:56      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

通道

题意:区间涂色,询问区间内颜色相同的个数

思路:将原区间划分乘sqrt(n)个区间,每次暴力查询和跟新两边的区间,中间的区间直接用hash存每种颜色的节点的数量。这里用到了类似线段树的lazy思想,区间成段修改直接打个标记,等到要划分这个区间的时候先把标记传下去,然后更新

代码:

技术分享
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <map>
#define MAXN 100005
int n,m,bsize,bnum,x[MAXN];
struct hash_block{
     int cls,size;
     std::map<int,int> mp;
}b[350];
void pushdown(int id){
    hash_block &hb=b[id];
    if(hb.cls!=-1){
        for(int i=id*bsize;i<id*bsize+hb.size;i++)x[i]=hb.cls;
        hb.mp.clear(),hb.mp[hb.cls]=hb.size;
        hb.cls=-1;
    }
}
void update(int l,int r,int c){
    int lb=l/bsize,rb=r/bsize,ans=0;
    for(int i=lb+1;i<rb;i++)b[i].cls=c;
    if(lb!=rb){
        pushdown(lb);pushdown(rb);
        for(int i=l;i<lb*bsize+b[lb].size;i++)
            b[lb].mp[x[i]]--,b[lb].mp[c]++,x[i]=c;
        for(int i=rb*bsize;i<=r;i++)
            b[rb].mp[x[i]]--,b[rb].mp[c]++,x[i]=c;
    }else{
    pushdown(lb);
    for(int i=l;i<=r;i++)
        b[lb].mp[x[i]]--,b[lb].mp[c]++,x[i]=c;
    }
}
int query(int l,int r,int c){
    int lb=l/bsize,rb=r/bsize,ans=0;
    for(int i=lb+1;i<rb;i++){
        if(b[i].cls==c)ans+=b[i].size;
        else if(b[i].cls==-1&&b[i].mp.find(c)!=b[i].mp.end())ans+=b[i].mp[c];
    }
    if(lb!=rb){
        pushdown(lb);pushdown(rb);
        for(int i=l;i<lb*bsize+b[lb].size;i++)ans+=(x[i]==c);
        for(int i=rb*bsize;i<=r;i++)ans+=(x[i]==c);
    }else{
        pushdown(lb);
        for(int i=l;i<=r;i++)ans+=(x[i]==c);
    }
    return ans;
}
void initblock(){
    bsize=(int)sqrt(n+1e-8);
    bnum=(n-1)/bsize+1;
    for(int i=0;i<bnum;i++){
        b[i].mp.clear();
        b[i].cls=-1;
        b[i].size=std::min(i*bsize+bsize,n)-i*bsize;
    }
    for(int i=0;i<n;i++){
        scanf("%d",&x[i]);
        b[i/bsize].mp[x[i]]++;
    }
}
int q,l,r,z;
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        initblock();
        while(m--){
            scanf("%d%d%d%d",&q,&l,&r,&z);
            if(q==1)update(l,r,z);
            else printf("%d\n",query(l,r,z));
        }
    }
    return 0;
}
View Code

 

【分块】 HDU 4391 Paint The Wall

标签:

原文地址:http://www.cnblogs.com/Rojo/p/4736353.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!