传送门

Description

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

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

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

Input

第一行是两个正整数\(n,m\)

第二行\(n\)个数代表序列

接下来\(m\)行询问,每行四个整数\(l,r,a,b\)

Output

对每个询问输出一行两个用空格隔开的整数,分别代表答案

Hint

\(Forall:\)

\(1~\leq~n,m~\leq100000\)

Solution

多次查询没有修改,于是考虑莫队

一个非常显然的想法是对每个值的出现次数开桶,对第二问开权值桶,然后用树状数组维护前缀和,就可以做到单点修改区间查询了。复杂度\(O(n~\sqrt{n}~logm+mlogm)\),其中\(O(n~\sqrt{n}~logm)\)是修改复杂度,\(O(mlogm)\)是查询复杂度。于是发现前面一项复杂度过高,而后面一项完全不需要做到这样的复杂度。在一个操作复杂度过高,另一个操作复杂度压缩过度时,可以考虑将其中一个的复杂度降低,提升另一个的复杂度。比如这里考虑使用分块维护桶,单次修改复杂度\(O(1)\),查询复杂度\(O(\sqrt{n})\),总复杂度\(~O(~(n+m)~\sqrt{n}~)~\),可以通过本题

Code

#include<cmath>
#include<cstdio>
#include<algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a,b,c)
#endif
#define rg register
#define ci const int
#define cl const long long typedef long long int ll; template <typename T>
inline void qr(T &x) {
rg char ch=getchar(),lst=' ';
while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst == '-') x=-x;
} namespace IO {
char buf[120];
} template <typename T>
inline void qw(T x,const char aft,const bool pt) {
if(x < 0) {x=-x,putchar('-');}
rg int top=0;
do {IO::buf[++top]=x%10+'0';} while(x/=10);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
} const int maxn = 100010; int n,m;
int MU[maxn],belong[maxn],sa[maxn],bsa[maxn],sb[maxn],bsb[maxn]; struct Ask {
int l,r,a,b,num;
ll ans1,ans2;
inline bool operator<(const Ask &_others) const {
if(belong[this->l] != belong[_others.l]) return this->l < _others.l;
if(belong[this->l] & 1) return this->r < _others.r;
return this->r > _others.r;
}
};
Ask ask[maxn]; inline bool cmp(const Ask &_a,const Ask &_b) {
return _a.num < _b.num;
} int main() {
qr(n);qr(m);
for(rg int i=1;i<=n;++i) qr(MU[i]);
for(rg int i=1;i<=m;++i) {
qr(ask[i].l);qr(ask[i].r);qr(ask[i].a);qr(ask[i].b);ask[i].num=i;
}
for(rg int i=1,sn=sqrt(n);i<=n;++i) belong[i]=i/sn;
std::sort(ask+1,ask+1+m);
int prel=ask[1].l,prer=ask[1].l-1;
for(rg int i=1;i<=m;++i) { int l=ask[i].l,r=ask[i].r;
while(prel < l) {
if(!(--sa[MU[prel]])) --sb[MU[prel]],--bsb[belong[MU[prel]]];
--bsa[belong[MU[prel]]];
++prel;
}
while(prel > l) {
--prel;
if(!sa[MU[prel]]) ++sb[MU[prel]],++bsb[belong[MU[prel]]];
++bsa[belong[MU[prel]]];++sa[MU[prel]];
}
while(prer < r) {
++prer;
if(!sa[MU[prer]]) ++sb[MU[prer]],++bsb[belong[MU[prer]]];
++bsa[belong[MU[prer]]];++sa[MU[prer]];
}
while(prer > r) {
if(!(--sa[MU[prer]])) --sb[MU[prer]],--bsb[belong[MU[prer]]];
--bsa[belong[MU[prer]]];
--prer;
}
ll &ans1=ask[i].ans1,&ans2=ask[i].ans2;
int &a=ask[i].a,&b=ask[i].b;
int bl=belong[ask[i].a],br=belong[ask[i].b];
if(bl == br) {
for(rg int i=a;i<=b;++i) ans1+=sa[i],ans2+=sb[i];
continue;
}
for(rg int i=bl+1;i<br;++i) ans1+=bsa[i],ans2+=bsb[i];
for(rg int i=a;belong[i] == bl;++i) ans1+=sa[i],ans2+=sb[i];
for(rg int i=b;belong[i] == br;--i) ans1+=sa[i],ans2+=sb[i];
}
std::sort(ask+1,ask+1+m,cmp);
for(rg int i=1;i<=m;++i) {
qw(ask[i].ans1,' ',true);
qw(ask[i].ans2,'\n',true);
}
return 0;
}

Summary

修改复杂度过高,查询复杂度压缩过度时,考虑使用分块平衡复杂度。

最新文章

  1. split和join的用法
  2. 【iOS】Jenkins Gitlab持续集成打包平台搭建
  3. 学习微信小程序之css10外边距
  4. Reveal分析IOS界面,plist文件读取
  5. 收缩菜单 css变样
  6. 使用chrome联调不在同一个域的请求
  7. oracle和mssql中复制表的比较
  8. 利用API 建立Dependent Value Set
  9. ANDROID_MARS学习笔记_S05_002_给传感器注册listener
  10. 制作Net程序的帮助文档--总结
  11. COJ 0979 WZJ的数据结构(负二十一)
  12. css 设置 checkbox复选框控件的对勾√样式
  13. Python学习笔记 - 迭代Iteration
  14. How Tomcat Works 读书笔记 八 载入器 上
  15. Oracle ADDM报告生成和性能分析
  16. SSM框架整合环境构建——基于Spring4和Mybatis3
  17. About me &amp; 留言板
  18. PHP调用百度天气接口API
  19. 移动端 Retina屏border实现0.5px
  20. 05-Mirrorgate数据库信息

热门文章

  1. Paper Reading - Deep Captioning with Multimodal Recurrent Neural Networks ( m-RNN ) ( ICLR 2015 ) ★
  2. Hybrid APP基础篇(四)-&gt;JSBridge的原理
  3. 关于jsonp跨域的 实现
  4. GCD最大公约数
  5. GIT团队实战博客
  6. 404_NOTE_Foung_软工6
  7. 【IdentityServer4文档】- 使用密码保护 API
  8. HDU 5656 CA Loves GCD 01背包+gcd
  9. 关于初装kali linux 2.0时DEB文件安装失败的问题
  10. cat命令和EOF标识输出shell到文件