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

题面戳这里

思路:

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);
    }
}

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

时间: 2024-10-06 07:20:47

20181009noip HZ EZ两校联考sum(莫队,组合数学)的相关文章

10.29 FJ四校联考

//四校联考Rank 16 感觉很滋磁 (虽然考的时候抱怨厦门一中出的数学题很NOIP///) 圈地 [问题描述] n根长度不一定相同的木棍,至多可以对其中一根切一刀,然后用其中的任意根围一个三角形,求三角形的最大面积.设面积为S,输出16*S^2对998244353取模后的答案.特别地,无解输出-1. 注:退化的三角形(面积为零)不被认为是三角形,答案应该为-1. [输入文件] 输入文件为tri.in. 输入文件第一行包含两个正整数n和998244353. 第二行包含n个正整数,表示每根木棍的

九校联考 终&amp;启

one term's ending... class:12 school:130...130...130... 至今没有看到九校的排名,如果九校排名正常的话,那yyhs的学生也太可怕了...估计要三百开外了 语文是比较意外的分数,尽管选择题做得差,可是有史以来第一次下110....why 数学和英语都比预估的低. 政史地84 65 78,感觉最对不起历史老师...地理从来没好过. 物化技82 75 83,是时候改课了..... 明明下半学期一直在学文化课...现在连浙大线都考不上了.... 学考

四校联考2017.8.20T1填算式

由于T2和T3都太高深了太巧妙了,于是只会做T1,拿了95分.现提供95分做法与满分做法 数据范围:n≤13,1≤ai≤9,0≤k≤109 大意:给n个数,在其中填+?×,允许多个数合并为一个.求使得最终结果等于k的算式数量.(这不就是我们平常玩的24点的加强版吗?) 95分解法:我们注意到对于第一个数字,其前面的操作只能为加法,对于之后的每一个数字,我们都有四种操作:在前面填加号,减号,乘号:与前面的数字合并.注意到n的值很小,于是考虑深搜.用两个数组分别记这个算式的符号和数字,当深搜到最后的

2017-2-26福建四校联考

哎我好菜啊 从来没打过表的萌新这次想打个表结果打太多了长度超限了(后来发现根本没必要打表) ---------我是分割线 A.矩形 给定一个2*n的矩形,每个位置有一个正权值,你要把它恰好分成m个矩形,使得所有矩形的和的最大值最小并求出最小的最大值. n<=100000 m<=100 题解: 首先很显然m只是一个附加条件,如果你能分<m段,那么你一定能分m段. 看到最大值最小,最小值最大的问题,很自然想到二分答案. 然后我们用一个dp来check.用f[i]表示前i*2的矩形至少要分几段

八校联考第一场(20170917)

排列(permutation)题目描述]给定一个n*n 的矩阵f,你需要求出有多少个1~n 的排列x 满足对于1<=i≠j<=n,均有f[i,j]=min(x[i],x[j]),并输出字典序最小的一个.有多组数据.[输入数据]第一行一个整数t 表示数据组数.每组数据第一行一个正整数n.接下来n 行每行n 个整数,第i行第j 列的整数表示f[i,j].[输出数据]对于每组数据,如果不存在这样的排列,输出一行一个整数-1.否则输出两行,第一行一个整数表示排列个数对998244353 取模的结果,第

多校联考九场总结

总算考完了九套试题,天天早上坐五个小时,下午都会头痛的要死QAQ 不过考的貌似不错? 九场平均分 215.78 数一数考场上没有1A的题目吧(不算有毒的OJ卡我常数): 1.超立方体 QAQ 当时并不会FWT,矩阵乘法搞出系数来之后只能暴力贡献 然后输入的时候没有直接取模爆了long long,于是暴力也被炸飞了 后来学了FWT发现是水题 2.IP地址 没有使用合适的转化询问的方式 使得这道题目可以用打标记的方式来做 转化的一些经典方式:差分,叶节点查询转化为链求和,区间可减性查询转化为前缀查询

【NOIP2016提高A组五校联考4】label

题目 题目 20%算法 设\(f_{i,j}\)表示第i个节点选了j这个权值的方案数. 显然转移方程为,\[f_{i,j}=\Pi_{v=son(i)}(\sum_{k=1}^{j-k}f_{v,k}+\sum_{k=j+k}^{m}f_{v,k})\] 40%算法 接着上面的想法, 观察转移方程,发现,求和部分其实是两段连续的,那么将\(f_{i}\)求一个前缀和. 100%算法 观察\(f\)数组,发现其实\(f\)是对称的,而且中间的一段是相同的,设深度为x,那么前面就有\((x-1)k\

20170820四校联考

来看看IOIAu巨神zzx的名言 不用循环输入就会狗啊哥哥! 上题目: T1: 填算式(expr) [题目描述] 填算式是一种简单的数学游戏,可以形式化描述如下:n 个数字a1; a2; -- ; an 排成一排(1<= ai<=9),相邻两个数字之间有一个空格.你可以在每个空格内填入运算符+- * 之一,也可以不填,要求得到的算式的运算结果等于k.你的任务是计算有多少种不同的正确算式.比如n = 3,3 个数字为2; 2; 2,k = 24时,有两种不同的正确算式:22 + 2 = 24,2

【四校联考】点

[题目描述] 有n个点,初始时没有边.有m个操作,操作分为两种: (1) 在i和j之间增加一条无向边,保证1<=i,j<=n. (2) 删去最后添加的k条边,保证k<=当前边数. 你想要知道最多能选取多少个两两不连通的点,以及选取的方案数.在每次操作后输出这两个值.方案数对998244353取模. [输入数据] 第一行两个整数n,m.接下来m行每行第一个数表示操作类型,接下来2或1个数表示i,j或k. [输出数据] 对于每个操作,输出一行两个整数,用一个空格隔开. [样例输入] 3 7