您的位置:首页 > 其它

【莫队算法】bzoj3781 小B的询问

2014-11-28 15:58 302 查看
莫队经典。 开个数组维护a[i]出现的次数。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int Num,CH[12],f,c;
inline void R(int &x){
c=0;f=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c>='0'&&c<='9';c=getchar())(x*=10)+=(c-'0');
x*=f;
}
inline void P(int x){
if(x<10)putchar(x+'0');
else{P(x/10);putchar(x%10+'0');}
}
int ans,anss[50001];
int n,m,K,num[50001],a[50001],T[50001];
int sqr(const int &x){return x*x;}
struct ASK{int l,r,p;void Read(){R(l);R(r);}}Q[50001];
bool operator < (const ASK &a,const ASK &b){return num[a.l]!=num[b.l] ? num[a.l]<num[b.l] : a.r<b.r;}
void makeblock()
{
int sz=sqrt(n),sum=1; if(!sz) sz=1;
for(;sum*sz<n;++sum)
{
int r=sum*sz;
for(int i=sz*(sum-1)+1;i<=r;++i) num[i]=sum;
}
for(int i=sz*(sum-1)+1;i<=n;++i) num[i]=sum;
}
int main()
{
R(n);R(m);R(K);makeblock();
for(int i=1;i<=n;++i) R(a[i]);
for(int i=1;i<=m;++i) {Q[i].Read(); Q[i].p=i;}
sort(Q+1,Q+m+1);
for(int i=Q[1].l;i<=Q[1].r;++i){ans-=sqr(T[a[i]]);ans+=sqr(++T[a[i]]);}
anss[Q[1].p]=ans;
for(int i=2;i<=m;++i)
{
if(Q[i].l<Q[i-1].l){for(int j=Q[i-1].l-1;j>=Q[i].l;--j){ans-=sqr(T[a[j]]);ans+=sqr(++T[a[j]]);}}
else{for(int j=Q[i-1].l;j<Q[i].l;++j){ans-=sqr(T[a[j]]);ans+=sqr(--T[a[j]]);}}
if(Q[i].r<Q[i-1].r){for(int j=Q[i-1].r;j>Q[i].r;--j){ans-=sqr(T[a[j]]);ans+=sqr(--T[a[j]]);}}
else{for(int j=Q[i-1].r+1;j<=Q[i].r;++j){ans-=sqr(T[a[j]]);ans+=sqr(++T[a[j]]);}}
anss[Q[i].p]=ans;
} for(int i=1;i<=m;++i) P(anss[i]),puts("");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: