第四题 小学生计数题

提交文件: 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. 在原生APP中集成Unity容器

    随着技术的发展,越来越多的APP期望拥有3D,AR的能力.要达到这个目标可以选择使用原生开发,也可以使用Unity成熟的3D开发技术链,通过嵌入的方式将Unity容器嵌入到APP中.这里介绍的是通过嵌 ...

  2. 基于 JMeter API 开发性能测试平台

    背景: JMeter 是一个功能强大的性能测试工具,若开发一个性能测试平台,用它作为底层执行引擎在合适不过.如要使用其API,就不得不对JMeter 整个执行流程,常见的类有清楚的了解. 常用的 JM ...

  3. Codeforces 1254B1 - Send Boxes to Alice (Easy Version)

    题意 有\(n(1\leq n\leq 10^5)\)个盒子,每个盒子有\(a_i(0\leq a_i \leq 1)\)个糖果,你每一次可以将第\(i\)个盒子里的糖果放到第\(i-1\)或\(i+ ...

  4. qiankun微前端实践

    为什么要使用微前端 微前端架构具备以下几个核心价值: 技术栈无关 主框架不限制接入应用的技术栈,微应用具备完全自主权 独立开发.独立部署 微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步 ...

  5. RabbitMQ保姆级教程最佳实践

    一.消息队列介绍 1.消息队列概念 1.MQ全称为Message Queue,消息队列(MQ)是⼀种应⽤程序对应⽤程序的通信⽅法. 应⽤程序通过读写出⼊队列的消息(针对应⽤程序的数据)来通信,⽽⽆需专 ...

  6. 聊聊基于Alink库的决策树模型算法实现

    示例代码及相关内容来源于<Alink权威指南(Java版)> 概述 决策树模型再现了人们做决策的过程,该过程由一系列的判断构成,后面的判断基于前面的判断结果,不断缩小范围,最终推出结果. ...

  7. MongoDB 中的索引分析

    MongoDB 的索引 前言 MongoDB 使用 B 树还是 B+ 树索引 单键索引 创建单键索引 使用 expireAfterSeconds 创建 TTL 索引 复合索引 最左匹配原则 ESR 规 ...

  8. Node.js中常用的设计模式有哪些?

    本文由葡萄城技术团队首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 设计模式简介 设计模式是由经验丰富的程序员在日积月累中抽象出的用以解决通用问题的可 ...

  9. .NET6发布项目到腾讯云Windows2012R全网最详细教程

    注意:本次使用腾讯云作为本次的演示 1.创建服务器及连接 1.1 请先在腾讯云.阿里云等创建实例 1.2 打开远程连接工具输入在腾讯云获取的公网iP输入计算机 1.3 根据图片点击连接 1.4 输入服 ...

  10. Go 常用标准库之 fmt 介绍与基本使用

    Go 常用标准库之 fmt 介绍与基本使用 目录 Go 常用标准库之 fmt 介绍与基本使用 一.介绍 二.向外输出 2.1 Print 系列 2.2 Fprint 系列 2.3 Sprint 系列 ...