码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 2038 [2009国家集训队]小Z的袜子(hose)

时间:2016-04-16 13:51:43      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

莫队算法第一题。

强制类型转换没写,WA了好久才发现......

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

const int maxn=50000+10;
int n,m;
struct X
{
    int l,r,id;
    long long ans1,ans2;
} s[maxn];
int a[maxn];
int pos[maxn];
long long cnt[maxn];
long long Ans;
int L,R;

bool cmp(const X&a,const X&b)
{
    if(pos[a.l]==pos[b.l]) return a.r<b.r;
    return a.l<b.l;
}

bool cmp1(const X&a,const X&b)
{
    return a.id<b.id;
}

long long gcd(long long a,long long b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}

int main()
{
    scanf("%d%d",&n,&m);

    int sz=(int)sqrt(1.0*n);
    memset(cnt,0,sizeof cnt);
    Ans=0;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        pos[i]=i/sz;
    }
    for(int i=1; i<=m; i++)
    {
        scanf("%d%d",&s[i].l,&s[i].r);
        s[i].id=i;
    }
    sort(s+1,s+m+1,cmp);
    
    for(int i=s[1].l; i<=s[1].r; i++)
    {
        Ans=Ans+cnt[a[i]];
        cnt[a[i]]++;
    }
    L=s[1].l,R=s[1].r;

    s[1].ans1=2*Ans;
    s[1].ans2=(long long)(s[1].r-s[1].l+1)*(long long)(s[1].r-s[1].l);
    long long tmp=gcd(s[1].ans1,s[1].ans2);
    s[1].ans1/=tmp;
    s[1].ans2/=tmp;
    
    for(int i=2; i<=m; i++)
    {
        while(L<s[i].l)
        {
            cnt[a[L]]--;
            Ans=Ans-cnt[a[L]];
            L++;
        }
        while(L>s[i].l)
        {
            L--;
            Ans=Ans+cnt[a[L]];
            cnt[a[L]]++;
        }
        while(R<s[i].r)
        {
            R++;
            Ans=Ans+cnt[a[R]];
            cnt[a[R]]++;
        }
        while(R>s[i].r)
        {
            cnt[a[R]]--;
            Ans=Ans-cnt[a[R]];
            R--;
        }

        s[i].ans1=2*Ans;
        s[i].ans2=(long long)(s[i].r-s[i].l+1)*(long long)(s[i].r-s[i].l);
        long long tmp=gcd(s[i].ans1,s[i].ans2);
        s[i].ans1/=tmp;
        s[i].ans2/=tmp;
    }
    sort(s+1,s+m+1,cmp1);
    for(int i=1; i<=m; i++)
        printf("%lld/%lld\n",s[i].ans1,s[i].ans2);
    return 0;
}

 

BZOJ 2038 [2009国家集训队]小Z的袜子(hose)

标签:

原文地址:http://www.cnblogs.com/zufezzt/p/5398198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!