小Z的袜子 (莫队算法)

来源:互联网 发布:linux shell sleep 1s 编辑:程序博客网 时间:2024/06/11 02:56

题目链接


选我选我选我!!!


我就马一下学习资料= =


#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#define maxn 50005using namespace std;typedef long long LL;LL cnt[maxn];int color[maxn];int pos[maxn];struct foo{    int l,r,index;    LL up,down;    bool operator < (const foo &cmp)const    {        if(pos[l]==pos[cmp.l])return r<cmp.r;        return pos[l]<pos[cmp.l];    }} Q[maxn];bool cmp_id(const foo &a,const foo &b){    return a.index<b.index;}LL gcd(LL a,LL b){    return a%b==0?b:gcd(b,a%b);}void modify(int p,LL &ans,int add){    ans-=cnt[color[p]]*cnt[color[p]];    cnt[color[p]]+=add;    ans+=cnt[color[p]]*cnt[color[p]];}int main(){    int n,m;    scanf("%d%d",&n,&m);    int SIZE=(int)sqrt(n*1.0);    memset(cnt,0,sizeof cnt);    for(int i=1; i<=n; i++)    {        scanf("%d",&color[i]);        pos[i]=(i-1)/SIZE+1;    }    for(int i=0; i<m; i++)    {        scanf("%d%d",&Q[i].l,&Q[i].r);        Q[i].index=i;    }    sort(Q,Q+m);    LL ans=0;    for(int i=0,l=1,r=0; i<m; i++)    {        if(r<Q[i].r)        {            for(r=r+1; r<=Q[i].r; r++)                modify(r,ans,1);            r--;        }        if(r>Q[i].r)        {            for(; r>Q[i].r; r--)                modify(r,ans,-1);        }        if(l<Q[i].l)        {            for(; l<Q[i].l; l++)                modify(l,ans,-1);        }        if(l>Q[i].l)        {            for(l=l-1; l>=Q[i].l; l--)                modify(l,ans,1);            l++;        }        if(Q[i].l==Q[i].r)        {            Q[i].up=0;            Q[i].down=1;            continue;        }        Q[i].up=ans-(Q[i].r-Q[i].l+1);        Q[i].down=(LL)(Q[i].r-Q[i].l+1)*(Q[i].r-Q[i].l);        LL k=gcd(Q[i].up,Q[i].down);        Q[i].up/=k;        Q[i].down/=k;    }    sort(Q,Q+m,cmp_id);    for(int i=0; i<m; i++)    {        printf("%lld/%lld\n",Q[i].up,Q[i].down);    }    return 0;}


0 0
原创粉丝点击