bzoj3236 [Ahoi2013]作业

网友投稿 272 2022-09-16

bzoj3236 [Ahoi2013]作业

​​ 题目描述

此时己是凌晨两点,刚刚做了Codeforces的小A掏出了英语试卷。英语作业其实不算多,一个小时刚好可以做完。然后是一个小时可以做完的数学作业,接下来是分别都是一个小时可以做完的化学,物理,语文……小A压力巨大。

这是小A碰见了一道非常恶心的数学题,给定了一个长度为n的数列和若干个询问,每个询问是关于数列的区间表示数列的第1个数到第r个数),首先你要统计该区间内大于等于a,小于等于b的数的个数,其次是所有大于等于a,小于等于b的,且在该区间中出现过的数值的个数。

小A望着那数万的数据规模几乎绝望,只能向大神您求救,请您帮帮他吧。

输入输出格式

输入格式:

第一行n,m

接下来n个数表示数列

接下来m行,每行四个数l,r,a,b

输出格式:

输出m行,分别对应每个询问,输出两个数,分别为在1到i?这段区间中大小在[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

复习莫队..

这题gty的妹子序列 应该几乎差不多

考虑每次询问莫队处理 然后针对权值分块 每次查询sqrt(n)即可完成

没有权值范围差评 差点不敢写 不过写了就A了 还是好评的

#include#include#include#includeusing namespace std;inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++;}inline int read(){ int x=0,f=1;char ch=gc(); while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();} while(isdigit(ch)) x=x*10+ch-'0',ch=gc(); return x*f;}const int N=1e6+10;const int M=1e6+10;struct node{ int l,r,a,b,id;}qr[N];int sum1[500],sum2[500];// sum1->all sum2-> kindint ans1[M],ans2[M]; //ans1->all ans2->kindint b[N],a[N],cnt[N],nn,n,m; inline bool cmp(const node &aa,const node &bb){ return b[aa.l]==b[bb.l]?aa.r0;return; } for (int i=l;i<=b[l]*nn;++i) ans1[id]+=cnt[i],ans2[id]+=cnt[i]>0; for (int i=(b[r]-1)*nn+1;i<=r;++i) ans1[id]+=cnt[i],ans2[id]+=cnt[i]>0; for (int i=b[l]+1;iqr[i].l) change(--cl,1); while(crqr[i].r) change(cr--,-1); query(qr[i].a,qr[i].b,qr[i].id); }for (int i=1;i<=m;++i) printf("%d %d\n",ans1[i],ans2[i]); return 0;}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:云游四方|在迎接世界第一缕阳光的海岛,体验少年派的奇幻漂流!
下一篇:cf861a
相关文章

 发表评论

暂时没有评论,来抢沙发吧~