博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【uoj#209】[UER #6]票数统计 组合数+乱搞
阅读量:4310 次
发布时间:2019-06-06

本文共 1936 字,大约阅读时间需要 6 分钟。

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

  • 序列的前 $x_i$ 个位置中,恰好有 $y_i$ 个 $1$ ;
  • 序列的后 $y_i$ 个位置中,恰好有 $x_i$ 个 $1$ ;

求有多少个序列满足所有限制条件。答案可能很大,只需要输出它对 $998244353$ 取模后的结果即可。


题解

组合数+乱搞

显然当 $x>y$ 时条件为前缀限制,$x<y$ 时条件为后缀限制。

既有前缀限制,又有后缀限制的情况下,我们枚举总共1的个数,把后缀限制转化为前缀限制。

如果所有限制均有 $x\ne y$ 则可以直接使用组合数计算。预处理组合数,单次计算的时间复杂度是 $O(n)$ 的。

当有 $x=y$ 时,显然只需要考虑所有 $x=y$ 限制中 $x$ 最大的限制即可,总方案数为 满足前缀+满足后缀-满足前缀和后缀。

时间复杂度 $O(n^2)$ 。

#include 
#include
#include
#define N 1010#define M 5010#define mod 998244353using namespace std;int n , ax[N] , ay[N] , at , bx[N] , by[N] , bt , c[M][M] , v[M];int solve(int x){ int i , last = 0 , ans = 1; memset(v , -1 , sizeof(v)); v[0] = 0 , v[n] = x; for(i = 1 ; i <= at ; i ++ ) { if(v[ax[i]] != -1 && v[ax[i]] != ay[i]) return 0; v[ax[i]] = ay[i]; } for(i = 1 ; i <= bt ; i ++ ) { if(v[n - bx[i]] != -1 && v[n - bx[i]] != x - by[i]) return 0; v[n - bx[i]] = x - by[i]; } for(i = 1 ; i <= n ; i ++ ) { if(v[i] != -1) { if(v[i] < v[last]) return 0; ans = 1ll * ans * c[i - last][v[i] - v[last]] % mod , last = i; } } return ans;}int main(){ int T; scanf("%d" , &T); while(T -- ) { at = bt = 0; int m , i , j , x , y , p = 0 , mx = 0 , ans = 0; scanf("%d%d" , &n , &m); for(i = 1 ; i <= m ; i ++ ) { scanf("%d%d" , &x , &y) , mx = max(mx , min(x , y)); if(x > y) ax[++at] = x , ay[at] = y; else if(x < y) bx[++bt] = y , by[bt] = x; else p = max(p , x); } c[0][0] = 1; for(i = 1 ; i <= n ; i ++ ) { c[i][0] = 1; for(j = 1 ; j <= i ; j ++ ) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod; } for(i = mx ; i <= n ; i ++ ) { at ++ , ax[at] = ay[at] = p , ans = (ans + solve(i)) % mod; bt ++ , bx[bt] = by[bt] = p , ans = (ans - solve(i) + mod) % mod; at -- , ans = (ans + solve(i)) % mod , bt -- ; } printf("%d\n" , ans); } return 0;}

 

转载于:https://www.cnblogs.com/GXZlegend/p/8681422.html

你可能感兴趣的文章
设计模式09_代理模式
查看>>
设计模式10_桥接
查看>>
设计模式11_装饰器
查看>>
设计模式12_外观模式
查看>>
设计模式13_享元模式
查看>>
设计模式14_组合结构
查看>>
设计模式15_模板
查看>>
海龟交易法则01_玩风险的交易者
查看>>
CTA策略02_boll
查看>>
vnpy通过jqdatasdk初始化实时数据及历史数据下载
查看>>
设计模式19_状态
查看>>
设计模式20_观察者
查看>>
vnpy学习10_常见坑02
查看>>
用时三个月,终于把所有的Python库全部整理了!拿去别客气!
查看>>
pd.stats.ols.MovingOLS以及替代
查看>>
vnpy学习11_增加测试评估指标
查看>>
资金流入流出计算方法
查看>>
海龟交易法则07_如何衡量风险
查看>>
海龟交易法则08_风险与资金管理
查看>>
海龟交易法则09_海龟式积木
查看>>