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

20181009noip HZ EZ两校联考sum(莫队,组合数学)

时间:2018-10-09 22:17:46      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:end   https   span   src   stdout   open   include   分治   blog   

题面戳这里

思路:

noip考莫队???!!!

考场上死活没往这方面想啊!!!数据分治忘写endl50pts滚粗了

这里每个询问都有n,m两个参数

我们可以把它看做常规莫队中的l和r

然后利用组合数的可递推性质就好了

相信改变m大家都会写,n呢?

看图:

技术分享图片

我们发现,$S_n^m = S_{n-1}^m \times 2 - C_n^{m+1} + C_{n-1}^{m+1}$

(因为杨辉三角的性质)

所以n也可以递推

套个莫队就好了

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define rii register int i
#define rij register int j
#define int long long
const int p=1e9+7;
using namespace std;
struct que{
    int n,m,ans,bh;
}x[100005];
int ny[100005],jc[100005],jcny[100005],q,sy[100005],nn,nm,ans;
void qny()
{
    ny[1]=1;
    ny[0]=1;
    for(rii=2;i<=100000;i++)
    {
        ny[i]=(p-p/i)*ny[p%i]%p;
    }
}
void jic()
{
    jcny[0]=1;
    jc[1]=1;
    jcny[1]=1;
    for(rii=2;i<=100000;i++)
    {
        jc[i]=jc[i-1]*i;
        jc[i]%=p;
        jcny[i]=jcny[i-1]*ny[i];
        jcny[i]%=p;
    }
}
void ycl()
{
    qny();
    jic();
}
bool cmp1(que lk,que kl)
{
    if(sy[lk.n]==sy[kl.n])
    {
        return lk.m<kl.m;
    }
    return lk.n<kl.n;
}
bool cmp2(que lk,que kl)
{
    return lk.bh<kl.bh;
}
int c(int n,int m)
{
    int kkk=jcny[m];
    kkk*=jc[n];
    kkk%=p;
    kkk*=jcny[n-m];
    kkk%=p;
    return kkk;
}
void cn(int zl)
{
    if(zl==1)
    {
        ans*=2;
        ans-=c(nn+1,nm+1);
        ans+=c(nn,nm+1);
        ans+=p;
        ans%=p;
    }
    if(zl==-1)
    {
        ans+=c(nn,nm+1);
        ans-=c(nn-1,nm+1);
        ans+=p;
        ans%=p;
        ans*=ny[2];
        ans%=p;
    }
}
void cm(int zl)
{
    if(zl==1)
    {
        ans+=c(nn,nm+1);
    }
    else
    {
        ans-=c(nn,nm);
        ans+=p;
    }
    ans%=p;
}
signed main()
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    ycl();
    scanf("%lld",&q);
    scanf("%lld",&q);
    int len=316;
    for(rii=1;i<=100000;i++)
    {
        sy[i]=i/len+1;
    }
    for(rii=1;i<=q;i++)
    {
        scanf("%lld%lld",&x[i].n,&x[i].m);
        x[i].bh=i;
    }
    sort(x+1,x+q+1,cmp1);
    nn=1,nm=0,ans=1;
    for(rii=1;i<=q;i++)
    {
        if(x[i].m<nn)
        {
            while(nm>x[i].m)
            {
                cm(-1);
                nm--;
            }
            while(nm<x[i].m)
            {
                cm(1);
                nm++;
            }
            while(nn<x[i].n)
            {
                cn(1);
                nn++;
            }
            while(nn>x[i].n)
            {
                cn(-1);
                nn--;
            }
        }
        while(nn<x[i].n)
        {
            cn(1);
            nn++;
        }
        while(nn>x[i].n)
        {
            cn(-1);
            nn--;
        }
        while(nm>x[i].m)
        {
            cm(-1);
            nm--;
        }
        while(nm<x[i].m)
        {
            cm(1);
            nm++;
        }
        x[i].ans=ans;
    }
    sort(x+1,x+q+1,cmp2);
    for(rii=1;i<=q;i++)
    {
        printf("%lld\n",x[i].ans);
    }
}

 

20181009noip HZ EZ两校联考sum(莫队,组合数学)

标签:end   https   span   src   stdout   open   include   分治   blog   

原文地址:https://www.cnblogs.com/ztz11/p/9763251.html

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