• Codeforces 1295F Good Contest


    Codeforces 1295F Good Contest

    题意:序列长度为n,每个数等可能的取值于区间([l_i,r_i]),求这个序列单调不减的可能性。((2leq nleq 50))

    将区间离散化,表示成若干个不相交的区间和。
    例如[1,6],[2,8],[3,5] ,离散化成5块 : 1:[1,1] 2:[2,2] 3:[3,5] 4:[6,6] 5:[7,8]
    新区间:[1,4],[2,5],[3,3]

    考虑f[i][j]表示前i个数,第i个数在第j块的可能情况数。
    考虑ki都在第j块里的情况,答案为f[k-1][1j-1] + calc(k,i),calc(k,i)表示k和i都在这一块里,即n个数里可重复选m个的组合数。
    所以转移(f[i][j]=sum_{k} sum_{p=1}^{j-1}f[k][p]+calc(k+1,i))

    最后答案除上(prod_{i=1}^n (r_i-l_i+1))

    #include <bits/stdc++.h>
    #define all(x) (x).begin(),(x).end()
    #define ll long long
    using namespace std;
    
    const ll mol = 998244353;
    const int maxn = 1000;
    int l[maxn + 11],r[maxn + 11],R[maxn + 11],L[maxn + 11];
    vector <int> v;
    ll inv[maxn + 11];
    ll f[maxn + 11][maxn + 11];
    
    ll add(ll a,ll b) { a += b; if (a >= mol) a -= mol; return a; }
    ll qpow(ll a,ll b) { 
    	ll ans = 1;
    	while (b) { 
    		if (b & 1) ans = ans * a % mol;
    		a = a * a % mol;
    		b >>= 1;
    	} 
    	return ans;
    } 
    void pre() {
    	inv[0] = 1;
    	for (int i = 1; i <= 500; i++) inv[i] = inv[i - 1] * qpow(i , mol - 2) % mol;
    } 
    ll C(int n,int m) {
    	ll ans = 1;
    	for (int i = n - m + 1; i <= n; i++) ans = ans * i % mol;
    	return ans * inv[m] % mol;
    }
    
    int main() {
    	int n;
    	pre();
    	scanf("%d" , &n);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d %d",&l[i],&r[i]);
    		v.push_back(l[i]);
    		v.push_back(r[i] + 1);
    	}
    	reverse(l + 1 , l + 1 + n); reverse(r + 1 , r + 1 + n);
    	sort(all(v));
    	v.erase(unique(all(v)) , v.end());
    	for (int i = 1; i <= n; i++) {
    		L[i] = lower_bound(all(v) , l[i]) - v.begin() + 1;
    		R[i] = lower_bound(all(v) , r[i] + 1) - v.begin();
    	}
    	int m = v.size() - 1;
    	for (int i = 0; i <= m; i++) f[0][i] = 1;
    	for (int i = 1; i <= n; i++){ 
    		for (int j = L[i]; j <= R[i]; j++){ 
    			for (int k = i; k ; k--) {
    				if (R[k] < j || L[k] > j) break;
    				f[i][j] = add(f[i][j] , f[k - 1][j - 1] * C(i - k + v[j] - v[j - 1] , i - k + 1) % mol);
    			} 
    		} 
    		for (int k = 1; k <= m; k++)
    				f[i][k] = add(f[i][k] , f[i][k - 1]);
    	} 
    	ll ans = f[n][m];
    	for (int i = 1; i <= n; i++) ans = ans * qpow(r[i] - l[i] + 1 , mol - 2) % mol;
    	printf("%lld
    " , ans);
    } 
    
    
  • 相关阅读:
    PLSQL登录弹出空白框如何解决
    mongodb常用命令
    js多线程?
    Rhino -- 基于java的javascript实现
    [原创]在Docker上部署mongodb分片副本集群。
    [原创]在Linux系统Ubuntu14.04上安装部署docker。
    [原创]Win7、Win8、Win10始终以管理员身份运行程序。
    [原创]WPF应用MediaPlayer播放声音断续、不全解决方案
    [原创]C#引用C++编译的dll
    [原创]导出CSV文件,特殊字符处理。
  • 原文地址:https://www.cnblogs.com/Embiid/p/12270050.html
Copyright © 2020-2023  润新知