传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3236
一把辛酸泪
看完题面就想到莫队了
又看见了底下一行小字:
wangyisong神犇加强的数据估计莫队就过不了吧……
纠结了好久最终决定还是写莫队
然后就是WA+RE+TLE
就当我认定莫队必挂的时候看到了ydc神犇的莫队题解
交上去……90sA了
卧槽继续搞我的常数!!!
常数日志:
使用fread读入
使用puts输出
预处理pos
加上inline
交——RE
使用getchar读入
使用printf输出
不预处理pos
继续使用inline
交——RE
关闭inline
预处理pos
交——TLE
使用inline
把树状数组从类改成两个函数
交——TLE
对着ydc神犇的标程改改改改
交——TLE
都一样了怎么还T……
然后发现了一句话
inline bool operator<(const qes oth)const{
return pos[l]<pos[oth.l]||(pos[l]==pos[oth.l]/sqrtn&&r<oth.r);
}
真想一头撞死
改,交——RE
RE了!??!?!?!?!
又发现了一句话
const int maxn=1e5+5;
int ans1[maxn],ans2[maxn];
一头撞死++
我再交——
终于A了55555555
Code:
#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
using namespace std;
const int maxn=1e5+5;
int n,m,sqrtn,a[maxn];
int vis[maxn],pos[maxn],ans1[maxn*10],ans2[maxn*10];
int d1[maxn],d2[maxn];
void read(int &res){
res=0;char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);res=res*10+c-'0',c=getchar());
}
inline int get1(int x){int o=0;while(x)o+=d1[x],x-=lowbit(x);return o;};
inline void updata1(int x,int f){while(x<=n)d1[x]+=f,x+=lowbit(x);}
inline int get2(int x){int o=0;while(x)o+=d2[x],x-=lowbit(x);return o;};
inline void updata2(int x,int f){while(x<=n)d2[x]+=f,x+=lowbit(x);}
struct qes{
int l,r,a,b,id;
inline bool operator<(const qes oth)const{
return pos[l]<pos[oth.l]||(pos[l]==pos[oth.l]&&r<oth.r);
}
}q[maxn*10];
int main(){
read(n);read(m);
sqrtn=sqrt(n);
for(int i=1;i<=n;++i)read(a[i]);
for(int i=1;i<=n;++i)pos[i]=i/sqrtn;
for(int i=1;i<=m;i++){
read(q[i].l);read(q[i].r);
read(q[i].a);read(q[i].b);q[i].id=i;
}sort(q+1,q+1+m);
int L=1,R=1;
updata1(a[1],1);
updata2(a[1],1);
vis[a[1]]++;
for(int i=1;i<=m;i++){
while(L>q[i].l){
L--;
updata1(a[L],1);
if(!vis[a[L]])updata2(a[L],1);
vis[a[L]]++;
}
while(R<q[i].r){
R++;
updata1(a[R],1);
if(!vis[a[R]])updata2(a[R],1);
vis[a[R]]++;
}
while(L<q[i].l){
updata1(a[L],-1);
if(!--vis[a[L]])updata2(a[L],-1);
L++;
}
while(R>q[i].r){
updata1(a[R],-1);
if(!--vis[a[R]])updata2(a[R],-1);
R--;
}
ans1[q[i].id]=get1(q[i].b)-get1(q[i].a-1);
ans2[q[i].id]=get2(q[i].b)-get2(q[i].a-1);
}
for(int i=1;i<=m;i++)
printf("%d %d\n",ans1[i],ans2[i]);
}