1. 程式人生 > >HDU 4391 Paint The Wall 分塊HASH

HDU 4391 Paint The Wall 分塊HASH

/**
HDU 4391 Paint The Wall 分塊HASH
連結:http://acm.hdu.edu.cn/showproblem.php?pid=4391
區間計數+區間推平;
分塊HASH+標記;
************tricks**********
map<>mp;時間複雜度  竟然被稱為O(1);
vector維護升序  二分查log複雜度不可避免 感覺複雜度差不多呀;
估計是資料針對排序所需複雜度多了一個log;
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=1e5+7;
int n,m,blo,x[maxn],pos[maxn];

struct node{
     int cls,sz;
     map<int,int>mp;
}b[500];

void pushdown(int id){
    if(b[id].cls!=-1){
        for(int i=(id-1)*blo+1;i<=min(n,id*blo);i++) x[i]=b[id].cls;
        b[id].mp.clear(),b[id].mp[b[id].cls]=b[id].sz;
        b[id].cls=-1;
    }
}

void update(int l,int r,int c){
    for(int i=pos[l]+1;i<=pos[r]-1;i++) b[i].cls=c;

    if(pos[l]!=pos[r]){
        pushdown(pos[l]);pushdown(pos[r]);
        for(int i=l;i<=pos[l]*blo;i++) b[pos[l]].mp[x[i]]--,b[pos[l]].mp[c]++,x[i]=c;
        for(int i=(pos[r]-1)*blo+1;i<=r;i++) b[pos[r]].mp[x[i]]--,b[pos[r]].mp[c]++,x[i]=c;
    }
    else{
        pushdown(pos[l]);
        for(int i=l;i<=r;i++) b[pos[l]].mp[x[i]]--,b[pos[l]].mp[c]++,x[i]=c;
    }
}

int query(int l,int r,int c){
    int ans=0;
    for(int i=pos[l]+1;i<=pos[r]-1;i++){
        if(b[i].cls==c) ans+=b[i].sz;
        else if(b[i].cls==-1&&b[i].mp.find(c)!=b[i].mp.end()) ans+=b[i].mp[c];
    }
    if(pos[l]!=pos[r]){
        pushdown(pos[l]);pushdown(pos[r]);
        for(int i=l;i<=pos[l]*blo;i++) ans+=(x[i]==c);
        for(int i=(pos[r]-1)*blo+1;i<=r;i++)ans+=(x[i]==c);
    }
    else{
        pushdown(pos[l]);
        for(int i=l;i<=r;i++)ans+=(x[i]==c);
    }
    return ans;
}

int q,l,r,z;

int main(){
    while(~scanf("%d %d",&n,&m)){
        blo=(int)sqrt(n*1.0);
        for(int i=1;i<=n;i++) pos[i]=(i-1)/blo+1;
        for(int i=1;i<=pos[n];i++){
            b[i].mp.clear();
            b[i].cls=-1;
            b[i].sz=min(i*blo,n)-(i-1)*blo;
        }
        for(int i=1;i<=n;i++) {
            scanf("%d",&x[i]);
            b[pos[i]].mp[x[i]]++;
        }
        while(m--){
            scanf("%d %d %d %d",&q,&l,&r,&z);l++,r++;
            if(q==1) update(l,r,z);
            else printf("%d\n",query(l,r,z));
        }
    }
    return 0;
}