bzoj 2038 小Z的袜子 莫队模板

来源:互联网 发布:如何提高精气神 知乎 编辑:程序博客网 时间:2024/06/11 06:08

n个袜子每个都有一个颜色,求他给的区间 取两个袜子正好同色的概率
复杂度nsqrt(n);
先分sqrt(n)块 然后把区间按最左边界所在的块排序,如果所在块相等按右边届从小到大排序。
定义此时的l,r,ans(起始为1,0,0),然后枚举区间改变l,r,ans

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define LL long long#define MAXN 50010using namespace std;int n,m,unit;int num[MAXN],co[MAXN];struct node{       int l,r,i;}no[51000];LL gcd(LL a,LL b){   while(b)   {       LL t = b;       b = a%b;       a = t;    }   return a;}class node2{    public:        LL a,b;       inline void gao()       {            LL t = gcd(a,b);            a/=t;            b/=t;          }    }ans1[MAXN];inline bool cmp(node no1,node no2)//排序{     if(no1.l/unit!=no2.l/unit)return no1.l<no2.l;     return no1.r<no2.r;}inline void work()//莫队{     int l = 1,r = 0;     LL ans = 0;     for(int i=0;i<m;i++)     {         while(r>no[i].r)         {             ans-=(LL)num[co[r]]*(num[co[r]]-1);             num[co[r]]--;             ans+=(LL)num[co[r]]*(num[co[r]]-1);                 r--;         }         while(r<no[i].r)         {             r++;             ans-=(LL)num[co[r]]*(num[co[r]]-1);             num[co[r]]++;             ans+=(LL)num[co[r]]*(num[co[r]]-1);             }         while(l<no[i].l)         {             ans-=(LL)num[co[l]]*(num[co[l]]-1);             num[co[l]]--;             ans+=(LL)num[co[l]]*(num[co[l]]-1);             l++;            }         while(l>no[i].l)         {             l--;             ans-=(LL)num[co[l]]*(num[co[l]]-1);             num[co[l]]++;             ans+=(LL)num[co[l]]*(num[co[l]]-1);             }         ans1[no[i].i].a = ans;         ans1[no[i].i].b = ((LL)no[i].r-no[i].l+1)*(no[i].r-no[i].l);         ans1[no[i].i].gao();     }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        scanf("%d",&co[i]);    for(int i=0;i<m;i++)    {        scanf("%d%d",&no[i].l,&no[i].r);        no[i].i = i;    }    unit = sqrt(m+0.001);    sort(no,no+m,cmp);    work();    for(int i=0;i<m;i++)        printf("%lld/%lld\n",ans1[i].a,ans1[i].b);    return 0;}
0 0
原创粉丝点击