BZOJ 2038 小Z的袜子(hose) [莫队算法]

来源:互联网 发布:电钢琴 手感 知乎 编辑:程序博客网 时间:2024/06/12 01:31

题意:给你n只袜子的颜色,询问在袜子区间【L,R】中选出两只相同颜色的袜子的概率

题解:询问量比较大,明显用莫队

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<iostream>#define N 50005using namespace std;typedef long long ll;ll a[N];ll pos[N];ll num[N];ll len;struct node{ll l,r,id;node(){}node(ll l,ll r,ll id){this->l=r;this->r=r;this->id=id;}}q[N];ll ansa[N],ansb[N];bool cmp(node a,node b){return pos[a.l]<pos[b.l]||pos[a.l]==pos[b.l]&&a.r<b.r;}ll modify(ll p,ll add){    ll sum=2*add*num[a[p]]+1;    num[a[p]]+=add;    return sum;}ll gcd(ll a,ll b){if(b!=0)return gcd(b,a%b);return a;}int main(){ll n,m;scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);len=(ll)sqrt((double)n+0.1);for(ll i=1;i<=n;i++)pos[i]=(i-1)/len+1;for(ll i=0;i<m;i++){scanf("%lld%lld",&q[i].l,&q[i].r);q[i].id=i;}sort(q,q+m,cmp);ll ans=0;ll l=1,r=0;for(ll i=0;i<m;i++){if(r<q[i].r){for(r=r+1;r<=q[i].r;r++)ans+=modify(r,1);r--;}if(q[i].l<l){for(l=l-1;l>=q[i].l;l--)ans+=modify(l,1);l++;}if(r>q[i].r){for(;r>q[i].r;r--)ans+=modify(r,-1);}if(q[i].l>l){for(;l<q[i].l;l++)ans+=modify(l,-1);}if(q[i].l==q[i].r)        {            ansa[q[i].id]=0,ansb[q[i].id]=1;            continue;        }ansa[q[i].id]=ans-(q[i].r-q[i].l+1);ansb[q[i].id]=(q[i].r-q[i].l+1)*(q[i].r-q[i].l);ll g=gcd(ansa[q[i].id],ansb[q[i].id]);ansa[q[i].id]/=g;ansb[q[i].id]/=g;}for(ll i=0;i<m;i++)printf("%lld/%lld\n",ansa[i],ansb[i]);}

阅读全文
0 0
原创粉丝点击