HYSBZ 2038 小Z的袜子 莫队算法

来源:互联网 发布:美国p2p软件 编辑:程序博客网 时间:2024/06/02 20:48
#include <cstdio>#include <iostream>#include <set>#include <vector>#include <cstring>#include <string>#include <algorithm>#include <cmath>#include <map>#include <queue>#include <iomanip>using namespace std;const int size=111111;typedef long long ll;typedef double dd;typedef pair<int,int> P;int n,m,a[size];int Q[size],cnt;ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}struct node{    int l,r,id;}b[size];int cmp(node a,node b){    return Q[a.l]<Q[b.l]||(Q[a.l]==Q[b.l]&&a.r<b.r);}ll ans,num[size],ret[size],len[size];ll add(int a,int k){    ll ret=num[a]*num[a];    num[a]+=k;    return num[a]*num[a]-ret;}void work(){    int l=1,r=num[a[1]]=ans=1;    for(int i=0;i<m;i++){        while(b[i].r>r)r++,ans+=add(a[r],1);        while(b[i].r<r)ans+=add(a[r],-1),r--;        while(b[i].l>l)ans+=add(a[l],-1),l++;        while(b[i].l<l)l--,ans+=add(a[l],1);        ret[b[i].id]=ans;    }}int main(){    while(cin>>n>>m){        cnt=sqrt(n);        for(int i=1;i<=n;i++){            scanf("%d",&a[i]);            num[a[i]]=0;            Q[i]=(i-1)/cnt+1;        }        for(int i=0;i<m;i++){            scanf("%d%d",&b[i].l,&b[i].r);            b[i].id=i;            len[i]=b[i].r-b[i].l+1;        }        sort(b,b+m,cmp);        work();        for(int i=0;i<m;i++){            ll _g=gcd(ret[i]-len[i],len[i]*(len[i]-1));            printf("%lld/%lld\n",(ret[i]-len[i])/_g,len[i]*(len[i]-1)/_g);        }    }}

0 0
原创粉丝点击