您的位置:首页 > 其它

BZOJ 2038 莫队

2016-12-20 21:55 120 查看
(我不会告诉你我是抄的黄学长的题解的……)

//By SiriusRen
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
#define N 100050
int n,m,a
,pos
,ans,ch
;
struct Ask{int x,y,id,ansx,ansy;}ask
;
bool cmp(Ask a,Ask b){
if(pos[a.x]==pos[b.x])return a.y<b.y;
return a.x<b.x;
}
bool cmp2(Ask a,Ask b){return a.id<b.id;}
int gcd(int x,int y){return y?gcd(y,x%y):x;}
void update(int num,int wei){
ans-=ch[a[num]]*ch[a[num]];
ch[a[num]]+=wei;
ans+=ch[a[num]]*ch[a[num]];
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
int block=sqrt(n);
for(int i=1;i<=n;i++)
pos[i]=(i-1)/block+1;
for(int i=1;i<=m;ask[i].id=i,i++)
scanf("%lld%lld",&ask[i].x,&ask[i].y);
sort(ask+1,ask+1+m,cmp);
for(int i=1,l=1,r=0;i<=m;i++){
for(;r<ask[i].y;r++)update(r+1,1);
for(;r>ask[i].y;r--)update(r,-1);
for(;l<ask[i].x;l++)update(l,-1);
for(;l>ask[i].x;l--)update(l-1,1);
if(ask[i].x==ask[i].y){
ask[i].ansx=0,ask[i].ansy=1;
continue;
}
ask[i].ansx=ans-(r-l+1);
ask[i].ansy=(r-l+1)*(r-l);
int GCD=gcd(ask[i].ansx,ask[i].ansy);
ask[i].ansx=ask[i].ansx/GCD,ask[i].ansy=ask[i].ansy/GCD;
}
sort(ask+1,ask+1+m,cmp2);
for(int i=1;i<=m;i++){
printf("%lld/%lld\n",ask[i].ansx,ask[i].ansy);
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  莫队