P4396 [AHOI2013]作业
题目描述
此时己是凌晨两点,刚刚做了Codeforces的小A掏出了英语试卷。英语作业其实不算多,一个小时刚好可以做完。然后是一个小时可以做完的数学作业,接下来是分别都是一个小时可以做完的化学,物理,语文......小A压力巨大。
这是小A碰见了一道非常恶心的数学题,给定了一个长度为n的数列和若干个询问,每个询问是关于数列的区间表示数列的第l个数到第r个数),首先你要统计该区间内大于等于a,小于等于b的数的个数,其次是所有大于等于a,小于等于b的,且在该区间中出现过的数值的个数。
小A望着那数万的数据规模几乎绝望,只能向大神您求救,请您帮帮他吧。
输入输出格式
输入格式:第一行n,m
接下来n个数表示数列
接下来m行,每行四个数l,r,a,b
输出格式:输出m行,分别对应每个询问,输出两个数,分别为在l到r这段区间中大小在[a,b]中的数的个数,以及大于等于a,小于等于b的,且在该区间中出现过的数值的个数(具体可以参考样例)。
输入输出样例
输入样例#1:
3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
输出样例#1:
2 2
1 1
3 2
2 1
说明
N<=100000,M<=100000
Solution:
本题是上题妹子序列的加强版?反正还是莫队。
第二问就是上题的询问(只不过数据弱化了),第一问也很简单,只需要在分块时多维护一下值域范围内的数的个数,其它就是一些细节问题的处理了。
代码:
/*Code by 520 -- 10.4*/ #include<bits/stdc++.h> #define il inline #define ll long long #define RE register #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++) #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--) using namespace std; const int N=100005; int n,m,a[N],ln[N],rn[N]; int sum[5005],ppx[5005],c[N],bl[N],ans[N][2]; struct node{ int l,r,a,b,id; bool operator < (const node &a) const {return bl[l]==bl[a.l]?r<a.r:l<a.l;} }q[N]; int gi(){ int a=0;char x=getchar(); while(x<'0'||x>'9') x=getchar(); while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar(); return a; } il void add(int v){ppx[bl[v]]++,sum[bl[v]]+=((++c[v])==1);} il void del(int v){ppx[bl[v]]--,sum[bl[v]]-=((--c[v])==0);} il void query(node x){ int l=bl[x.a],r=bl[x.b],res1=0,res2=0; for(RE int i=l+1;i<r;i++) res1+=ppx[i],res2+=sum[i]; if(l==r) For(i,x.a,x.b) res1+=c[i],res2+=(c[i]>0); else { For(i,x.a,rn[l]) res1+=c[i],res2+=(c[i]>0); For(i,ln[r],x.b) res1+=c[i],res2+=(c[i]>0); } ans[x.id][0]=res1,ans[x.id][1]=res2; } int main(){ n=gi(),m=gi(); int blo=sqrt(n); For(i,1,n) a[i]=gi(),bl[i]=(i-1)/blo+1; For(i,1,n) { rn[bl[i]]=i; if(!ln[bl[i]]) ln[bl[i]]=i; } For(i,1,m) q[i]=node{gi(),gi(),gi(),gi(),i}; sort(q+1,q+m+1); for(RE int i=1,l=1,r=0;i<=m;i++){ while(l<q[i].l) del(a[l]),++l; while(l>q[i].l) --l,add(a[l]); while(r<q[i].r) ++r,add(a[r]); while(r>q[i].r) del(a[r]),--r; query(q[i]); } For(i,1,m) printf("%d %d\n",ans[i][0],ans[i][1]); return 0; }
PS:~蒟蒻写博客不易,转载请注明出处,万分感谢!~