题目

做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】票数统计的更多相关文章

  1. 【uoj#209】[UER #6]票数统计 组合数+乱搞

    题目描述 一个长度为 $n$ 的序列,每个位置为 $0$ 或 $1$ 两种.现在给出 $m$ 个限制条件,第 $i$ 个限制条件给出 $x_i$ .$y_i$ ,要求至少满足以下两个条件之一: 序列的 ...

  2. uoj#209. 【UER #6】票数统计

    http://uoj.ac/problem/209 当x!=y时,这个限制条件是确定的,可以枚举总通过数,用组合数计算,当x==y时,这个限制条件表示前x个全部通过或后x个全部通过,只有最大的x有用, ...

  3. 【UOJ 209】【UER #6】票数统计

    题解: jls的题目还是比较好的 首先比较显然我们可以分析出 当x<y时,显然只能满足前缀条件 针对这一档部分分,是个简单的组合数 考虑一下后缀限制,发现真的不好搞.. 看了题解发现,枚举总共的 ...

  4. UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)

    题目链接 http://uoj.ac/contest/47/problem/455 题解 模拟费用流,一个非常神奇的东西. 本题即为WC2019 laofu的讲课中的Problem 8,经典的老鼠进洞 ...

  5. [UOJ#245][UER#7]天路(近似算法)

    允许5%的相对误差,意味着我们可以只输出$\log_{1.05} V$种取值并保证答案合法.并且注意到答案随着区间长度而单增,故取值不同的答案区间是$O(\log_{1.05} V)$的. 于是初始x ...

  6. 如何利用Excel设计一个唱票统计系统?

    具体操作如下: 首先需要一个如下的数据结构. 唱票数G列区域,不能手动输入候选人票数,这样很不方便,所以我们需要一个窗体控件,用点击鼠标的方法来实现唱票.在“开发工具-插入-数值调节钮”下图3处,然后 ...

  7. 投票系统 & 简易js刷票脚本

    早就听说有什么刷票脚本,微博投票等等相关的投票都有某些人去刷票. 试一下吧,兴许自己也会刷票呢?捣鼓了几个小时,终于有所眉目. (1)投票系统 要刷票,就得先有个投票界面. 当然,可以直接去各个投票网 ...

  8. JSAAS的Activiti会签开发扩展处理

    1.什么是会签? 在流程业务管理中,任务是通常都是由一个人去处理的,而多个人同时处理一个任务,这种任务我们称之为会签任务.这种业务需求很常见,如一个请款单,领导审批环节中,就需要多个部门领导签字.在流 ...

  9. HDU 3639 Hawk-and-Chicken (强连通缩点+DFS)

    <题目链接> 题目大意: 有一群孩子正在玩老鹰抓小鸡,由于想当老鹰的人不少,孩子们通过投票的方式产生,但是投票有这么一条规则:投票具有传递性,A支持B,B支持C,那么C获得2票(A.B共两 ...

随机推荐

  1. CF 。E2. Stars Drawing (Hard Edition) (DP)

    Description: 定义一个星星由 '*' 组成,形状为一个对称的“十”字型,大小为星星 1/2 的横长(或纵长)减一(如题目中的图).给出一个 n*m 的图,判断是不是每一个 '*' 都能属于 ...

  2. ElasticSearch Roaring bitmap 和跳表联合查询

    ElasticSearch Roaring map 先把所有数按65535划分, 划分方法就是求商和余数,商代表数字最终在哪一块,余数代表最终在块内的数字 比如 1, 65536, 65537, 13 ...

  3. Jackson环境安装设置

    本地环境设置 由于Jackson是基于Java编程语言的,所以需要设置Java开发环境,这里介绍如何下载安装设置Java.请按照以下步骤来设置环境. Java SE是免费的,点击下载链接:下载Java ...

  4. 常用的一些js事件及案例

    比如金额需要显示的时候转换成有千分位,小数点后保留2位等.去编辑的时候,又要格式化,把逗号都去掉.网上找了段代码,但是再次编辑会有问题,修改了一下,代码如下: function outputMoney ...

  5. laydate box-sizingCSS就会变形

    *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;/* box-sizing:border-box; */} 解决:在/laydat ...

  6. 连接分析算法-HITS-算法

    转自http://blog.csdn.net/Androidlushangderen/article/details/43311943 参考资料:http://blog.csdn.net/hguisu ...

  7. 46-Ubuntu-系统信息-1-date和cal查看系统时间

    序号 命令 作用 01 date 查看系统时间 02 cal calendar查看日历,-y选项可以查看一年的日历

  8. Android网络(3):HttpClient作client,Tomcat Servlet作server的交互演示样例

    前面相继介绍了Android网络编程里的Socket传输图片.HttpURLConnection,今天看HttpClient. 第一部分:JavaEE版的Eclipse配置Tomcat [备注:开发后 ...

  9. C# 基于创建一个mysql 连接池

    创建一个连接池操作类 using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using Syste ...

  10. 2018-2-13-win10-edge扩展

    title author date CreateTime categories win10 edge扩展 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23 ...