zoukankan      html  css  js  c++  java
  • CF1295F

    题目

    (a_i)在范围([l_i, r_i])等概率取值,求序列({a_i})非递增的概率。(nle 50)(l_ile r_i le 998244351)

    题解

    即求序列非递增的方案数。

    由于区间范围非常大,而区间数又很少。因此可以离散化端点,给区间分段。这样分下来总段数就是(O(n))级别了。可以使用dp解决。

    这样每个大区间,每分成若干个连续的右闭左开的小区间,以及最后一个左闭右闭仅仅包含一个数的小区间。

    (dp[i][j])代表前(i)个区间,当前在第(j)个小区间的方案数。转移很好想,关键在于求解一个区间内(k)个非递增位置的方案数。这个用差分的方法,转化为差值大于等于0,差值求和小于等于区间长度,可以用隔板法解决。

    注意最后左闭右闭小区间的处理即可。

    #include <bits/stdc++.h>
    
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
    typedef long long ll;
    
    using namespace std;
    /*-----------------------------------------------------------------*/
    
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    #define INF 0x3f3f3f3f
    
    const int N = 1e2 + 10;
    const int MX = 1e5 + 10;
    const int M = 998244353;
    const double eps = 1e-5;
    
    ll dp[N][N];
    ll rfact[MX];
    typedef pair<int, int> PII;
    PII segs[N];
    vector<int> num;
    
    
    inline ll qpow(ll a, ll b, ll m) {
    	ll res = 1;
    	while(b) {
    		if(b & 1) res = (res * a) % m;
    		a = (a * a) % m;
    		b = b >> 1;
    	}
    	return res;
    }
    
    int main() {
    	IOS;
    	rfact[0] = 1;
    	for(int i = 1; i < MX; i++) {
    		rfact[i] = rfact[i - 1] * qpow(i, M - 2, M) % M;
    	}
    	num.push_back(0);
    	int n;
    	cin >> n;
    	ll tot = 1;
    	for(int i = 1; i <= n; i++) {
    		int l, r;
    		cin >> l >> r;
    		tot = (r - l + 1) * tot % M;
    		segs[i] = {l, r};
    		num.push_back(l);
    		num.push_back(r);
    	}
    	sort(num.begin(), num.end());
    	num.erase(unique(num.begin(), num.end()), num.end());
    	for(int i = 1; i <= n; i++) {
    		segs[i].first = lower_bound(num.begin(), num.end(), segs[i].first) - num.begin();
    		segs[i].second = lower_bound(num.begin(), num.end(), segs[i].second) - num.begin();
    	}
    	for(int i = 0; i < N; i++) dp[0][i] = 1;
    	for(int i = 1; i <= n; i++) {
    		int l = segs[i].first, r = segs[i].second;
    		for(int j = r; j >= l; j--) {
    			int rg;
    			if(j - 1 >= l) rg = num[j] - num[j - 1];
    			else rg = 1;
    			ll pw = rg;
    			for(int k = i - 1; k >= 0; k--) {
    
    				if(k && segs[k].first == j) 
    					dp[i][j] = (dp[i][j] + dp[k][j] % M * pw % M * rfact[i - k] % M) % M;
    				else
    					dp[i][j] = (dp[i][j] + dp[k][j + 1] % M * pw % M * rfact[i - k] % M) % M;
    				pw = pw * (rg + i - k) % M;
    				if(!(segs[k].second >= j && segs[k].first < j)) break;
    			}
    			dp[i][j] = (dp[i][j] + dp[i][j + 1]) % M;
    		}
    		for(int j = l - 1; j >= 0; j--) {
    			dp[i][j] = dp[i][j + 1];
    		}
    	}
    	cout << dp[n][0] * qpow(tot, M - 2, M) % M << endl;
    }
    
  • 相关阅读:
    c语言结构体数组引用
    c语言结构体数组定义的三种方式
    如何为SAP WebIDE开发扩展(Extension),并部署到SAP云平台上
    SAP SRM ABAP Webdynpro和CFCA usb key集成的一个原型开发
    使用SAP API portal进行SAP SuccessFactors的API测试
    SAP UI5应用里的页面路由处理
    在SAP WebIDE Database Explorer里操作hdi实例
    如何使用SAP事务码SAT进行UI应用的性能分析
    使用SAP WebIDE进行SAP Cloud Platform Business Application开发
    SAP CRM WebClient UI ON_NEW_FOCUS的用途
  • 原文地址:https://www.cnblogs.com/limil/p/15267773.html
Copyright © 2011-2022 走看看