uoj#209【UER #6】票数统计
做UER的A题涨信心
首先我们注意到这个所谓的至少有一条正确在\(x\)和\(y\)不相等的时候非常弱,当\(x<y\)时,只有可能是后\(y\)位用户有\(x\)个通过;当\(x>y\)时,只有可能是前\(x\)位用户有\(y\)个通过。也就是说这些信息都能被转化成一些用来限制前后缀和的信息。
设\(pre_i\)表示序列的前缀和,对于一条前\(x\)位用户有\(y\)个通过的限制,我们可以拆成\(pre_x=y\);对于一条后\(y\)位用户有\(x\)个通过的信息,可以视为\(pre_n-pre_{n-y}=x\),即\(pre_{n-y}=pre_n-x\)。
如果我们知道\(pre_n\)的值,那么就只剩下了一些前缀和的信息了。所以我们可以直接枚举\(pre_n\)的值。这些关于前缀和的限制又将整个序列分割成了一些区间,每个区间的区间和也都被限制好了,直接使用组合数把每个区间的方案算出来就好了,答案就是每一个区间组合数的乘积。
但是上述的做法均不能处理\(x=y\)的情况,当\(x=y\)的时候,意味着有一个长度为\(x\)的前缀或后缀全都是\(1\)。这个\(x\)越大限制性必然越强,于是我们只需要考虑最大的\(x=y\),满足了最大的\(x=y\)剩下的\(x=y\)必然也都满足了。
我们枚举这个\(x=y\)限制前缀还是限制后缀,限制前缀就拆成\(pre_x=x\),限制后缀就拆成\(pre_{n-x}=x\)。但是如果有一种方案既有一段全是\(1\)的前缀,也有一段全是\(1\)的后缀,就会被计算两次。所以我们把两条限制条件都加上,再减掉这样的方案就好了。
代码
#include<bits/stdc++.h>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=5e3+5;
const int mod=998244353;
int T,n,m,M;
int fac[maxn],ifac[maxn],inv[maxn];
int a[maxn],b[maxn],c[maxn],d[maxn],t[2],pre[maxn];
inline int C(int n,int m) {
return m>n?0:1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
inline int solve(int sum) {
for(re int i=1;i<=t[0];i++) {
if(pre[a[i]]!=-1&&pre[a[i]]!=c[i]) return 0;
pre[a[i]]=c[i];
}
for(re int i=1;i<=t[1];i++) {
if(pre[n-b[i]]!=-1&&pre[n-b[i]]!=sum-d[i]) return 0;
pre[n-b[i]]=sum-d[i];
}
if(pre[0]!=-1&&pre[0]!=0) return 0;
pre[0]=0;int l=0,tot=1;
for(re int i=1;i<=n;i++) {
if(pre[i]==-1) continue;
if(pre[i]<pre[l]) return 0;
tot=1ll*tot*C(i-l,pre[i]-pre[l])%mod;l=i;
}
return tot;
}
int main() {
T=read();fac[0]=ifac[0]=inv[1]=1;
for(re int i=1;i<maxn;i++) fac[i]=1ll*fac[i-1]*i%mod;
for(re int i=2;i<maxn;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(re int i=1;i<maxn;i++) ifac[i]=1ll*ifac[i-1]*inv[i]%mod;
while(T--) {
n=read(),m=read();int x,y;t[0]=t[1]=M=0;
for(re int i=1;i<=m;i++) {
x=read(),y=read();
if(x<y) b[++t[1]]=y,d[t[1]]=x;
if(x>y) a[++t[0]]=x,c[t[0]]=y;
if(x==y) M=max(M,x);
}
int ans=0,now=M;
for(re int i=1;i<=t[0];i++) now=max(now,c[i]);
for(re int i=1;i<=t[1];i++) now=max(now,d[i]);
for(re int i=now;i<=n;i++) {
memset(pre,-1,sizeof(pre));
pre[n]=i,pre[M]=M;
ans=(ans+solve(i))%mod;
if(!M) continue;
memset(pre,-1,sizeof(pre));
pre[n]=i,pre[n-M]=i-M;
ans=(ans+solve(i))%mod;
memset(pre,-1,sizeof(pre));
pre[n]=i,pre[M]=M;pre[n-M]=i-M;
if(M==n-M&&M!=i-M) continue;
ans=(ans-solve(i)+mod)%mod;
}
printf("%d\n",ans);
}
return 0;
}
uoj#209【UER #6】票数统计的更多相关文章
- 【uoj#209】[UER #6]票数统计 组合数+乱搞
题目描述 一个长度为 $n$ 的序列,每个位置为 $0$ 或 $1$ 两种.现在给出 $m$ 个限制条件,第 $i$ 个限制条件给出 $x_i$ .$y_i$ ,要求至少满足以下两个条件之一: 序列的 ...
- uoj#209. 【UER #6】票数统计
http://uoj.ac/problem/209 当x!=y时,这个限制条件是确定的,可以枚举总通过数,用组合数计算,当x==y时,这个限制条件表示前x个全部通过或后x个全部通过,只有最大的x有用, ...
- 【UOJ 209】【UER #6】票数统计
题解: jls的题目还是比较好的 首先比较显然我们可以分析出 当x<y时,显然只能满足前缀条件 针对这一档部分分,是个简单的组合数 考虑一下后缀限制,发现真的不好搞.. 看了题解发现,枚举总共的 ...
- UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
题目链接 http://uoj.ac/contest/47/problem/455 题解 模拟费用流,一个非常神奇的东西. 本题即为WC2019 laofu的讲课中的Problem 8,经典的老鼠进洞 ...
- [UOJ#245][UER#7]天路(近似算法)
允许5%的相对误差,意味着我们可以只输出$\log_{1.05} V$种取值并保证答案合法.并且注意到答案随着区间长度而单增,故取值不同的答案区间是$O(\log_{1.05} V)$的. 于是初始x ...
- 如何利用Excel设计一个唱票统计系统?
具体操作如下: 首先需要一个如下的数据结构. 唱票数G列区域,不能手动输入候选人票数,这样很不方便,所以我们需要一个窗体控件,用点击鼠标的方法来实现唱票.在“开发工具-插入-数值调节钮”下图3处,然后 ...
- 投票系统 & 简易js刷票脚本
早就听说有什么刷票脚本,微博投票等等相关的投票都有某些人去刷票. 试一下吧,兴许自己也会刷票呢?捣鼓了几个小时,终于有所眉目. (1)投票系统 要刷票,就得先有个投票界面. 当然,可以直接去各个投票网 ...
- JSAAS的Activiti会签开发扩展处理
1.什么是会签? 在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务.这种业务需求很常见,如一个请款单,领导审批环节中,就需要多个部门领导签字.在流 ...
- HDU 3639 Hawk-and-Chicken (强连通缩点+DFS)
<题目链接> 题目大意: 有一群孩子正在玩老鹰抓小鸡,由于想当老鹰的人不少,孩子们通过投票的方式产生,但是投票有这么一条规则:投票具有传递性,A支持B,B支持C,那么C获得2票(A.B共两 ...
随机推荐
- 牛客Another Distinct Values
题目 我一开始试了一下n=3,发现不行,于是就猜测只有2可以,交了一发,通过了50%.所以我猜测只有偶数可以,奇数都不行. 中间空白部分放n=2的情况就行.因为n=2的情况时,最大只有2,所以我们可以 ...
- 为什么 Go 语言把类型放在后面
不是为了与众不同.而是为了更加清晰易懂. Rob Pike 曾经在 Go 官方博客解释过这个问题(原文地址:http://blog.golang.org/gos-declaration-syntax) ...
- CSS:CSS 布局 - 水平 & 垂直对齐
ylbtech-CSS:CSS 布局 - 水平 & 垂直对齐 1.返回顶部 1. CSS 布局 - 水平 & 垂直对齐 水平 & 垂直居中对齐 元素居中对齐 要水平居中对齐一个 ...
- 2019杭电多校第三场hdu6609 Find the answer(线段树)
Find the answer 题目传送门 解题思路 要想变0的个数最少,显然是优先把大的变成0.所以离散化,建立一颗权值线段树,维护区间和与区间元素数量,假设至少减去k才能满足条件,查询大于等于k的 ...
- POJ3630-Phone List-Trie字典树模板题
Given a list of phone numbers, determine if it is consistent in the sense that no number is the pref ...
- CentOS6.5下RPM包安装MySQL5.6.35
基本环境:VMware10.0+CentOS6.5+MySQL5.6.35 .查看操作系统相关 shell> cat /etc/issue shell> uname -a .创建需要下载r ...
- 树上倍增 hdu 2586
参考博客: 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<mat ...
- 笔记51 Mybatis快速入门(二)
Mybatis的CRUD 1.修改配置文件Category.xml,提供CRUD对应的sql语句. <?xml version="1.0" encoding="UT ...
- Batch - FOR /F Delims 和 Tokens 用法
原文地址: for /f命令之—Delims和Tokens用法&总结 作者:别逗了好么 在For命令语踞饽参数F中,最难理解的就是Delims和Tokens两个选项,本文简单的做一个比较和总拮 ...
- rasa学习(domain.yml、nlu.md、stories.md)(一)
一. 什么是rasa Rasa是一个用于自动文本和基于语音的对话的开源机器学习框架.了解消息,保持对话以及连接到消息传递通道和API Rasa分为Rasa core和 Rasa nlu两部分: Ras ...