2019南昌icpc网络赛 I题 二维偏序,分块套树状数组
https://nanti.jisuanke.com/t/41356
对于带修的二维数点,可以bit套主席树,也可CDQ三维偏序
但是最后我选择分块套BIT暴力...
复杂度为$m(blocksize+blocknum*logn)$
显然,如果按照$\sqrt{n}$分块,并不是最优的
我们可以适当的增加块的大小,减少块的数量,让$blocksize=blocknum*logn$
在这个题中,大概就是$\sqrt{1e6}$到$\sqrt{2e6}$之间吧
#include<bits/stdc++.h> #define rep(ii,a,b) for(int ii=a;ii<=b;++ii) using namespace std; const int maxn=2e5+10,maxm=6e2+10; int n,m; namespace fastio{ inline bool isdigit(char c){return c>=48&&c<=57;} const int maxsz=1e7; class fast_iostream{public: char ch=get_char(); inline char get_char(){ static char buffer[maxsz],*a=buffer,*b=buffer; return b==a&&(b=(a=buffer)+fread(buffer,1,maxsz, stdin),b==a)?EOF:*a++; } void operator>>(int& tmp){ tmp=0; while(!isdigit(ch)&&ch!=EOF){ch=get_char();}; if(ch==EOF)return ; do{tmp=ch-48+(tmp<<1)+(tmp<<3);}while(isdigit(ch=get_char())); } }; int top;char stk[8]; void put(int &tmp){ if (!tmp){putchar('0');return;} top=0; while(tmp)stk[++top]=tmp%10+'0',tmp/=10; while(top)putchar(stk[top--]); } }fastio::fast_iostream io; class bit{public: int node[maxn]; inline int lb(int x) {return x&(-x);} inline void update(int pos,int val){ for(;pos<=n;pos+=lb(pos)) node[pos]+=val; } inline int ask(int pos){ int sum=0; for(;pos>0;pos-=lb(pos)) sum+=node[pos]; return sum; } inline int query(int l,int r){ return ask(r)-ask(l-1); } }; int aa[maxn],bb[maxn]; class sqblock{public: struct block{ int l,r;bit tree; void update(int pos,int val) {tree.update(pos,val);} int query(int l,int r) {return tree.query(l,r);} }node[maxm]; int id[maxn],sz,cnt; void init(int n){ sz=sqrt(2e6); rep(i,1,n) id[i]=(i-1)/sz+1;cnt=id[n]; rep(i,1,cnt) node[i].l=(i-1)*sz+1; rep(i,1,cnt-1) node[i].r=i*sz; node[cnt].r=n; rep(i,1,n)if(aa[i]!=aa[i-1]) node[id[i]].update(aa[i],1); } void update(int x,int y){ if(x>1&&aa[x]!=aa[x-1]) node[id[x]].update(aa[x],-1); if(x<n&&aa[x+1]!=aa[x]) node[id[x+1]].update(aa[x+1],-1); aa[x]=y; if(x>1&&aa[x]!=aa[x-1]) node[id[x]].update(aa[x],1); if(x<n&&aa[x+1]!=aa[x]) node[id[x+1]].update(aa[x+1],1); } int query(int l,int r,int x,int y){ int posl=id[l],posr=id[r],ans=0; if(posl==posr) { rep(i,l,r) ans+=(aa[i]!=aa[i-1]&&aa[i]>=x&&aa[i]<=y); return ans; } rep(i,posl+1,posr-1) ans+=node[i].query(x,y); rep(i,l,node[posl].r) ans+=(aa[i]!=aa[i-1]&&aa[i]>=x&&aa[i]<=y); rep(i,node[posr].l,r) ans+=(aa[i]!=aa[i-1]&&aa[i]>=x&&aa[i]<=y); return ans; } }square; int x,y,b,c,d,e,a,ans; #define cin io int main() { cin>>n;cin>>m; rep(i,1,n) cin>>aa[i]; square.init(n); while(m--){ cin>>a; if(a==1){ cin>>x;cin>>y; if(aa[x]!=y) square.update(x,y); }else { cin>>b;cin>>c;cin>>d;cin>>e; ans=square.query(b,c,d,e); if(aa[b]==aa[b-1]&&aa[b]>=d&&aa[b]<=e) ans++; fastio::put(ans);putchar('\n'); } } }