第四题 小学生计数题

提交文件: counting.cpp

输入文件: counting.in

输出文件: counting.out

时间空间限制: 1 秒, 256 MB

作为 GDOI 的组题人,小 Y 需要整理手中已有的题目,考虑它们的难度以及所考察的知识点,然后将它们组成数套题目。小 Y 希望先能组出第一套题目,为了整套题目具有良好的区分度,在一套题目中:

• 所有题目的难度需要能排成等差数列;(也就是说,若将所有题目按难度从小到大排序,那么每相邻两

题的难度的差相等,这个差叫做公差)

• 每道题目的难度都是公差的倍数,公差不为 0;

• 需要有不少于 L 道题,不多于 R 道题。

现在小 Y 手里已经有了 m 道题目,其中难度为 \(a_i\) 的题有 \(c_i\) 道\((1 ≤ i ≤ n)\)。小 Y 希望能够道,他有多少种不同的方式能够组出一套题目。

在这道题目中,我们认为两种组题方式不同当且仅当 \(∃k(1 ≤ k ≤ m)\),使得一种方案包含第 \(k\) 道题而另一种方案不包含。由于答案可能很大,输出答案对 998244353 取模。

输入格式

第一行三个整数 \(n, m, L, R\),分别表示有多少种不同难度的题目、题目总数、一套题的题数下限和上限。

接下来 \(n\) 行,每行两个正整数 \(a_i\)

, \(c_i\),表示有 \(c_i\) 道难度为 \(a_i\) 的题\((1 ≤ i ≤ n)\)

输出格式

输出一个数,表示组题方案数对 998244353 取模的值

样例数据

6 12 2 3
2 2
4 2
6 2
8 2
12 2
16 2
64

数据范围

对于所有测试点,\(1 ≤ n, c_i ≤ 10^5,0 ≤ a_i ≤ 10^5,m =∑c_i ≤ 10^5,2 ≤ L ≤ R ≤ m\),\(a_i\) 两两不同。

测试点 n m \(a_i\) 特殊性质 1 特殊性质 2
1-4 $≤ 20 $ \(≤ 20\) \(≤ 20\) - -
5-6 $≤ 300 $ \(≤ 300\) $ ≤ 300$ - -
7-8 \(≤ 2000\) \(≤ 2000\) \(≤ 2000\) √ -
9-10 \(≤ 2000\) \(≤ 2000\) \(≤ 2000\) - √
11-12 \(≤ 2000\) \(≤ 2000\) \(≤ 2000\) - -
13-14 \(≤ 10^5\) \(≤ 10^5\) \(≤ 10^5\) √ -
15-16 \(≤ 10^5\) \(≤ 10^5\) \(≤ 10^5\) - √
17-20 \(≤ 10^5\) \(≤ 10^5\) \(≤ 10^5\) - -

特殊性质 1:满足 \(R − L ≤ 10\)

特殊性质 2:满足所有 \(c_i = 1\)

要求一定是倍数,那么就用调和级数行枚举。每次看\(a_i\)为\(i\)的倍数的情况下看当中有多少种选择方案。我们把所有\(a_i\)是\(i\)的倍数的情况提取出一个序列。

首先在输入时可以知道每种难度有多少个题可以选,枚举时每次选择一段连续的区间,区间要求长度大于\(l\)小于\(r\),然后将里面的所有难度题目数量相乘就是在这个区间中合法的数量。很容易发现,如果有\(0\)那么答案就是\(0\),所以0把序列分成了很多段,我们每次只截取一段计算。同时所有数相乘可以通过对他求一个前缀积的形式,设现在区间是\(l\)到\(r\),前缀积为\(t\),那么可以用\(t_r\div t_{l-1}\)来知道中间所有数的乘积。当然,由于要取模,所以还要用逆元。

整理一下思路,对于一个序列,我们先提取出所有的不含0的段,然后对于每个段,我们枚举长度在\(l\)到\(r\)之间的区间,然后对通过前缀积求出他的中间所有数的乘积,可以通过特殊性质1.

考虑再次优化,我们对于一个位置\(x\),如果把他作为区间的结尾,然后可以求出可能的开头,就是那结尾段减去\(l\)和\(r\)就是开头允许的范围\(tl,tr\),设那个位置逆元为\(v_i\),那么就求\(t_x\times v_i\)的和.但是我们可以对\(v\)求一个前缀和s,枚举\(x\)时可以用乘法分配律,直接加上\(t_x\times (s_{tr}-s_{tl-1})\)。复杂度降到\(nlog^2n\),可以通过此题。注意\(0\le a_i\),不要让数组越界。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,mod=998244353;
int n,m,l,r,v[N],lst,x,y,ret,s[N],t[N];
int pown(int x,int y)
{
if(y==0)
return 1;
int p=pown(x,y>>1);
if(y&1)
return 1LL*p*p%mod*x%mod;
return 1LL*p*p%mod;
}
int qumo(int x)
{
return (x%mod+mod)%mod;
}
void solve(int c,int x,int y)//公差为c,从x到y的答案。
{
s[x-1]=t[x-1]=1;
for(int i=x;i<=y;i++)
s[i]=1LL*s[i-1]*v[c*(i-1)]%mod;
for(int i=x;i<=y;i++)
t[i]=(t[i-1]+pown(s[i-1],mod-2))%mod;
for(int i=x;i<=y;i++)//枚举结尾
{
int p=max(x,i-r+1),q=i-l+1;
if(p>q)
continue;
ret=(ret+1LL*s[i]*qumo(t[q]-t[p-1])%mod)%mod;
}
}
int main()
{
// freopen("counting.in","r",stdin);
// freopen("counting.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&l,&r);
for(int i=1;i<=n;i++)
scanf("%d%d",&x,&y),v[x]=y;
for(int i=1;i<=100000;i++)//枚举公差
{
lst=0;
int j;
for(j=0;j*i<=100000;j++)
{
if(!v[j*i])
{
solve(i,lst+1,j);
lst=j+1;
}
}
solve(i,lst+1,j);
}
printf("%d",ret);
return 0;
}

[GDOIpj221D] 小学生计数题的更多相关文章

  1. 30道小学生四则运算题C/C++编程

    软件工程科课上,老师通过实例讲解什么是程序,程序和软件的区别,要求我们通过短时间写一道编程题, 题目就是编写30道小学生四则运算题.以下就是源代码: #include<iostream.h> ...

  2. ZOJ 3955 Saddle Point 校赛 一道计数题

    ZOJ3955 题意是这样的 给定一个n*m的整数矩阵 n和m均小于1000 对这个矩阵删去任意行和列后剩余一个矩阵为M{x1,x2,,,,xm;y1,y2,,,,,yn}表示删除任意的M行N列 对于 ...

  3. UOJ#428. 【集训队作业2018】普通的计数题

    #428. [集训队作业2018]普通的计数题 模型转化好题 所以变成统计有标号合法的树的个数. 合法限制: 1.根标号比子树都大 2.如果儿子全是叶子,数量B中有 3.如果存在一个儿子不是叶子,数量 ...

  4. D. Count the Arrays 计数题

    D. Count the Arrays 也是一个计数题. 题目大意: 要求构造一个满足题意的数列. \(n\) 代表数列的长度 数列元素的范围 \([1,m]\) 数列必须有且仅有一对相同的数 存在一 ...

  5. 【NOIP2017提高A组模拟9.7】JZOJ 计数题

    [NOIP2017提高A组模拟9.7]JZOJ 计数题 题目 Description Input Output Sample Input 5 2 2 3 4 5 Sample Output 8 6 D ...

  6. noip模拟44[我想我以后会碰见计数题就溜走的]

    noip模拟44 solutions 这一场抱零的也忒多了,我也只有45pts 据说好像是把几套题里面最难的收拾出来让我们考得 好惨烈啊,这次的考试我只有第一题骗了40pts,其他都抱零了 T1 Em ...

  7. FJOI2020 的两道组合计数题

    最近细品了 FJOI2020 的两道计数题,感觉抛开数据范围不清还卡常不谈里面的组合计数技巧还是挺不错的.由于这两道题都基于卡特兰数的拓展,所以我们把它们一并研究掉. 首先是 D1T3 ,先给出简要题 ...

  8. 「10.16晚」序列(....)·购物(性质)·计数题(DP)

    A. 序列 考场不认真读题会死..... 读清题就很简单了,分成若干块,然后块内递增,块外递减,同时使最大的块长为$A$ B. 购物 考场思路太局限了,没有发现性质, 考虑将$a_{i}$,排序前缀和 ...

  9. hdu-6415 Rikka with Nash Equilibrium dp计数题

    http://acm.hdu.edu.cn/showproblem.php?pid=6415 题意:将1~n*m填入一个n*m矩阵 问只有一个顶点的构造方案. 顶点的定义是:某数同时是本行本列的最大值 ...

  10. 【uoj428】普通的计数题

    Portal --> uoj428 Solution 不会胖子的一个log正解qwq只能怂怂滴写分治了qwq ​ 首先就是一个我想不到的转化qwq ​ 我们将第\(i\)次操作加入的数看成一个编 ...

随机推荐

  1. Selenium 学习笔记

    Selenium 学习笔记 Selenium 框架是时下在 Web 领域中被使用得最为广泛的自动化测试工具集之一,它能帮助程序员们面向指定的 Web 前端应用快速地开发出自动化测试用例,且能实现跨各种 ...

  2. Set Concept

    集合(Set)就是一种用来装事物的容器(或者称为结构),它所装的东西叫元素.集合这个容器的逻辑性很强,可以说是现在比较严谨的工具. 集合里的元素,它们可以是任何类型的数学对象:数字.符号.变量.空间中 ...

  3. 关于api数据接口应用

    在当今互联网时代,API数据接口应用已经成为各行各业不可替代的技术,它可以让开发者更加轻松地访问和使用各种功能和数据,从而提高开发效率和用户体验.下面就让我们来详细了解API数据接口应用的相关内容. ...

  4. Solution -「九省联考 2018」劈配

    Description Link. 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 轻车熟路的 Za ...

  5. HashMap底层源码分析

    HashMap底层原理实现 1.HashMap初始化 jdk1.8版本之后:数组+链表+红黑树实现,先去观看HashMap的构造方法: 构造方法: public HashMap() { this.lo ...

  6. a-2b

    a-2b   描述 输入两个高精度数a和b,求a-2b的值. 输入 输入两行,第一行是被减数a,第二行是减数b(a>2b并且a,2b的位数不同且不存在借位,且b+b不存在进位). 输出 一行,即 ...

  7. 在 Mac 上撰写和格式化备忘录-添加提醒-添加日历

    在 Mac 上撰写和格式化备忘录 您可以撰写备忘录以及更改备忘录的格式,例如,更改字体大小或对齐方式,或者使文本变为粗体.如果您使用的是升级后的 iCloud 备忘录或者储存在您 Mac 上的备忘录, ...

  8. docker入门加实战—从部署MySQL入门docker

    docker入门加实战-从部署MySQL入门docker docker部署MySQL 输入如下命令: docker run -d \ --name mysql \ -p 3306:3306 \ -e ...

  9. [ABC310D] Peaceful Teams 题解

    Peaceful Teams 题目大意 将 \(n\) 个人分成 \(T\) 组,要求每组不能包含敌对的人,问有多少种分法. 思路分析 注意到 \(n,T\) 均很小,考虑爆搜. 注意到直接枚举会枚举 ...

  10. 2023 版 Java和python开发线性代数探索

    目录 前景提示 需求 分析 1.初始化不需要指定矩阵的尺寸,并且可以直接传入数据. 2.可以计算2x2矩阵的逆 3.可以做2x2的矩阵乘法 Java版本开发 一. 开发详情 1.开发一个子类,如图所示 ...