小z的袜子

来源:互联网 发布:淘宝卖二手的叫什么 编辑:程序博客网 时间:2024/04/27 07:42

在学了莫队算法之后,又去搞了此题,主要是找转移式子上,莫队算法还是很好理解的。

#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<cmath>#define LL long longusing namespace std;LL gcd(LL a,LL b){    if(b==0)return a;    return gcd(b,a%b);}const int maxn = 50050;int n,m,sqrtn,c[maxn],num[maxn];struct node{    int l,r,i;     LL  a,b;} u[maxn];int cmp(node a,node b){    if(a.r/sqrtn==b.r/sqrtn)        return a.l<b.l;    return a.r/sqrtn<b.r/sqrtn;}int comp(node a,node b){    return a.i<b.i;}int main(){    while(~scanf("%d %d",&n,&m))    {        memset(num,0,sizeof(num));        for(int i=1; i<=n; i++)scanf("%d",&c[i]);        for(int i=0; i<m; i++)scanf("%d %d",&u[i].l,&u[i].r),u[i].i=i;        sqrtn=sqrt(n);        sort(u,u+m,cmp);        int x=1,y=0;        LL temp=0;        for(int i=0; i<m; i++)        {            while(y<u[i].r)            {                y++;                temp-=(LL)num[c[y]]*(LL)num[c[y]];                num[c[y]]++;                temp+=(LL)num[c[y]]*(LL)num[c[y]];            }            while(x<u[i].l)            {                temp-=(LL)num[c[x]]*(LL)num[c[x]];                num[c[x]]--;                temp+=(LL)num[c[x]]*(LL)num[c[x]];                x++;            }            while(y>u[i].r)            {                temp-=(LL)num[c[y]]*(LL)num[c[y]];                num[c[y]]--;                temp+=(LL)num[c[y]]*(LL)num[c[y]];                y--;            }            while(x>u[i].l)            {                x--;                temp-=(LL)num[c[x]]*(LL)num[c[x]];                num[c[x]]++;                temp+=(LL)num[c[x]]*(LL)num[c[x]];            }            u[i].a=(LL)(temp-(y-x+1));            u[i].b=(LL)(y-x+1)*(y-x);            if(u[i].a!=0)            {                LL k=gcd((LL)u[i].a,(LL)u[i].b);                u[i].a/=k;                u[i].b/=k;            }            else            {                u[i].a=0;                u[i].b=1;            }        }        sort(u,u+m,comp);        for(int i=0; i<m; i++)            printf("%lld/%lld\n",u[i].a,u[i].b);    }    return 0;}


0 0
原创粉丝点击