P4396 [AHOI2013]作业
P4396 [AHOI2013]作业
比较简单的莫队
思路:莫队搞区间
线段树/树状数组/分块搞权值
第一反应:排序+离散化+线段树+莫队
得到:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC optimize("-fgcse") #pragma GCC optimize("-fgcse-lm") #pragma GCC optimize("-fipa-sra") #pragma GCC optimize("-ftree-pre") #pragma GCC optimize("-ftree-vrp") #pragma GCC optimize("-fpeephole2") #pragma GCC optimize("-ffast-math") #pragma GCC optimize("-fsched-spec") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("-falign-jumps") #pragma GCC optimize("-falign-loops") #pragma GCC optimize("-falign-labels") #pragma GCC optimize("-fdevirtualize") #pragma GCC optimize("-fcaller-saves") #pragma GCC optimize("-fcrossjumping") #pragma GCC optimize("-fthread-jumps") #pragma GCC optimize("-funroll-loops") #pragma GCC optimize("-fwhole-program") #pragma GCC optimize("-freorder-blocks") #pragma GCC optimize("-fschedule-insns") #pragma GCC optimize("inline-functions") #pragma GCC optimize("-ftree-tail-merge") #pragma GCC optimize("-fschedule-insns2") #pragma GCC optimize("-fstrict-aliasing") #pragma GCC optimize("-fstrict-overflow") #pragma GCC optimize("-falign-functions") #pragma GCC optimize("-fcse-skip-blocks") #pragma GCC optimize("-fcse-follow-jumps") #pragma GCC optimize("-fsched-interblock") #pragma GCC optimize("-fpartial-inlining") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("-freorder-functions") #pragma GCC optimize("-findirect-inlining") #pragma GCC optimize("-fhoist-adjacent-loads") #pragma GCC optimize("-frerun-cse-after-loop") #pragma GCC optimize("inline-small-functions") #pragma GCC optimize("-finline-small-functions") #pragma GCC optimize("-ftree-switch-conversion") #pragma GCC optimize("-foptimize-sibling-calls") #pragma GCC optimize("-fexpensive-optimizations") #pragma GCC optimize("-funsafe-loop-optimizations") #pragma GCC optimize("inline-functions-called-once") #pragma GCC optimize("-fdelete-null-pointer-checks") #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<functional> #include<iostream> #include<map> using namespace std; const int N=100005; int n,m; int a[N]; int kans[N],kanss[N]; int be[N]; int len; int l=1,r=0,ans=0; struct node{ int l,r,a,b; int rank; }SSS[N]; inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } inline bool cmp(node x,node y) { return be[x.l]^be[y.l]?be[x.l]<be[y.l]:be[x.l]&1?x.r<y.r:x.r>y.r; } struct Sugment_Tree{ int t[N*3]; int u[N*3]; void ST(){ memset(t,0,sizeof(t)); memset(u,0,sizeof(u)); } #define il inline il void push_up(int num){ t[num]=(t[num<<1]+t[num<<1|1]); u[num]=(u[num<<1]+u[num<<1|1]); } il void upt(int l,int r,int num,int POS,int SUM){ if(l>POS||r<POS) return; if(l==r&&r==POS){ t[num]+=SUM; u[num]=(t[num]>0?1:0); return; } int mid=(l+r)>>1; upt(l,mid,num<<1,POS,SUM); upt(mid+1,r,num<<1|1,POS,SUM); push_up(num); } il int ask(int l,int r,int num,int LL,int RR){ if(l>RR||r<LL) return 0; if(l>=LL&&r<=RR){ return t[num]; } int mid=(l+r)>>1; return ask(l,mid,num<<1,LL,RR)+ask(mid+1,r,num<<1|1,LL,RR); } il int kakask(int l,int r,int num,int LL,int RR){ if(l>RR||r<LL) return 0; if(l>=LL&&r<=RR){ return u[num]; } int mid=(l+r)>>1; return kakask(l,mid,num<<1,LL,RR)+kakask(mid+1,r,num<<1|1,LL,RR); } }T; inline void AC(int pos,int val){ //pos是在原数列里的位置 T.upt(1,n,1,a[pos],val); } int main(){ n=read(),m=read(); len=pow(n,0.444); for(register int i=1;i<=n;++i){ a[i]=read(); } for(register int i=1;i<=n;++i) be[i]=(i/len)+1; T.ST(); for(register int i=1;i<=m;++i){ SSS[i].l=read(); SSS[i].r=read(); SSS[i].a=read(); SSS[i].b=read(); SSS[i].rank=i; } sort(SSS+1,SSS+m+1,cmp); for(register int i=1;i<=m;++i){ while(l<SSS[i].l) AC(l++,-1); while(l>SSS[i].l) AC(--l,1); while(r<SSS[i].r) AC(++r,1); while(r>SSS[i].r) AC(r--,-1); int LLL,RRR; LLL=SSS[i].a; RRR=SSS[i].b; kans[SSS[i].rank]=T.ask(1,n,1,LLL,RRR),kanss[SSS[i].rank]=T.kakask(1,n,1,LLL,RRR); } for(register int i=1;i<=m;++i) printf("%d %d\n",kans[i],kanss[i]); return 0; } /* 5 5 3 4 1 4 5 */
关于线段树,它死了......
表示不会树状数组,又人傻常数大
然后滚粗打分块,哎,打着打着就AC了
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC optimize("-fgcse") #pragma GCC optimize("-fgcse-lm") #pragma GCC optimize("-fipa-sra") #pragma GCC optimize("-ftree-pre") #pragma GCC optimize("-ftree-vrp") #pragma GCC optimize("-fpeephole2") #pragma GCC optimize("-ffast-math") #pragma GCC optimize("-fsched-spec") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("-falign-jumps") #pragma GCC optimize("-falign-loops") #pragma GCC optimize("-falign-labels") #pragma GCC optimize("-fdevirtualize") #pragma GCC optimize("-fcaller-saves") #pragma GCC optimize("-fcrossjumping") #pragma GCC optimize("-fthread-jumps") #pragma GCC optimize("-funroll-loops") #pragma GCC optimize("-fwhole-program") #pragma GCC optimize("-freorder-blocks") #pragma GCC optimize("-fschedule-insns") #pragma GCC optimize("inline-functions") #pragma GCC optimize("-ftree-tail-merge") #pragma GCC optimize("-fschedule-insns2") #pragma GCC optimize("-fstrict-aliasing") #pragma GCC optimize("-fstrict-overflow") #pragma GCC optimize("-falign-functions") #pragma GCC optimize("-fcse-skip-blocks") #pragma GCC optimize("-fcse-follow-jumps") #pragma GCC optimize("-fsched-interblock") #pragma GCC optimize("-fpartial-inlining") #pragma GCC optimize("no-stack-protector") #pragma GCC optimize("-freorder-functions") #pragma GCC optimize("-findirect-inlining") #pragma GCC optimize("-fhoist-adjacent-loads") #pragma GCC optimize("-frerun-cse-after-loop") #pragma GCC optimize("inline-small-functions") #pragma GCC optimize("-finline-small-functions") #pragma GCC optimize("-ftree-switch-conversion") #pragma GCC optimize("-foptimize-sibling-calls") #pragma GCC optimize("-fexpensive-optimizations") #pragma GCC optimize("-funsafe-loop-optimizations") #pragma GCC optimize("inline-functions-called-once") #pragma GCC optimize("-fdelete-null-pointer-checks") #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<functional> #include<iostream> #include<map> using namespace std; const int N=100005; const int M=505; int n,m; int a[N]; int kans[N],kanss[N]; int be[N]; int t[M]={0},tB[M]={0}; int lk[M],rk[M]; int len; int l=1,r=0; int happen[N]={0},has[N]={0}; struct node{ int l,r,a,b; int rank; }SSS[N]; inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } inline bool cmp(node x,node y) { return be[x.l]==be[y.l]?x.r<y.r:be[x.l]<be[y.l]; } struct Sugment_Tree{ #define il inline il void upt(int x,int v){ happen[x]+=v; t[be[x]]+=v; int u=has[x]; has[x]=happen[x]>0?1:0; if(u==1&&has[x]==0) tB[be[x]]--; else if(u==0&&has[x]==1) tB[be[x]]++; } il int ask(int l,int r){ if(be[l]==be[r]){ int ans=0; for(register int i=l;i<=r;i++){ ans+=happen[i]; } return ans; } else{ int ans=0; for(int i=l;i<=rk[be[l]];i++){ ans+=happen[i]; } for(int i=be[l]+1;i<=be[r]-1;i++) ans+=t[i]; for(int i=lk[be[r]];i<=r;i++){ ans+=happen[i]; } return ans; } } il int kakask(int l,int r){ if(be[l]==be[r]){ int ans=0; for(register int i=l;i<=r;i++){ ans+=has[i]; } return ans; } else{ int ans=0; for(int i=l;i<=rk[be[l]];i++){ ans+=has[i]; } for(int i=be[l]+1;i<=be[r]-1;i++) ans+=tB[i]; for(int i=lk[be[r]];i<=r;i++){ ans+=has[i]; } return ans; } } }T; inline void AC(int pos,int val){ //pos是在原数列里的位置 T.upt(a[pos],val); } int main(){ n=read(),m=read(); len=pow(n,0.5); for(register int i=1;i<=n;++i){ a[i]=read(); } for(register int i=1;i<=n;++i) be[i]=(i/len)+1; for(register int i=1;i<=n;++i){ if(!lk[be[i]]) lk[be[i]]=i; rk[be[i]]=i; } for(register int i=1;i<=m;++i){ SSS[i].l=read(); SSS[i].r=read(); SSS[i].a=read(); SSS[i].b=read(); SSS[i].rank=i; } sort(SSS+1,SSS+m+1,cmp); for(register int i=1;i<=m;++i){ while(l<SSS[i].l) AC(l++,-1); while(l>SSS[i].l) AC(--l,1); while(r<SSS[i].r) AC(++r,1); while(r>SSS[i].r) AC(r--,-1); int LLL,RRR; LLL=SSS[i].a; RRR=SSS[i].b; kans[SSS[i].rank]=T.ask(LLL,RRR),kanss[SSS[i].rank]=T.kakask(LLL,RRR); } for(register int i=1;i<=m;++i) printf("%d %d\n",kans[i],kanss[i]); return 0; } /* 5 5 3 4 1 4 5 */