HDU 4391 Paint The Wall 分塊HASH
阿新 • • 發佈:2018-11-19
/** 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; }