• HDU


    随机在[a,b] 选取一个数,随即在[c,d]选取一个数

    问  x + y 取模 p 同余 n 的概率

    其实就是计数问题。关键在于如何计数可以不重不漏。

    麻烦点在于分类讨论。对于这样的区间问题,先简化为0 , x 的区间。

    这里用到容斥原理,第一次做这样的题,不是很容易想到。

    分类讨论相对来说感觉还算简单?只要耐心讨论,总错不了

    #pragma warning(disable:4996)
    
    #include<iostream>
    #include<algorithm>
    #include<bitset>
    #include<tuple>
    #include<unordered_map>
    #include<fstream>
    #include<iomanip>
    #include<string>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<map>
    #include<set>
    #include<list>
    #include<queue>
    #include<stack>
    #include<sstream>
    #include<cstdio>
    #include<ctime>
    #include<cstdlib>
    #define pb push_back
    #define INF 0x3f3f3f3f
    #define inf 0x7FFFFFFF
    #define moD 1000000003
    #define pii pair<ll,ll>
    #define eps 1e-8
    #define equals(a,b) (fabs(a-b)<eps)
    #define bug puts("bug")
    #define re  register
    #define fi first
    #define se second
    typedef  long long ll;
    typedef unsigned long long ull;
    const ll MOD = 1e6 + 7;
    const int maxn = 3e5 +5;
    const double Inf = 10000.0;
    const double PI = acos(-1.0);
    using namespace std;
    
    ll a, b, c, d, p, m;
    
    ll f(ll a, ll b) {
        if (a < 0 || b < 0) return 0;
        ll ans = (a / p) * (b / p) * p;
        ll ma = a % p, mb = b % p;
        ans += (b / p) * (ma + 1) + (a / p) * (mb + 1);
        if (ma > m) {
            ans += min(mb, m) + 1;
            ll tt = (m - ma + p) % p;
            if (tt <= mb) ans += mb - tt + 1;
        }
        else {
            ll t = (m - ma + p) % p;
            if (t <= mb) ans += min(m - t + 1, mb - t + 1);
        }
        return ans;
    }
    
    ll gcd(ll a, ll b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    
    int main() {
        int T;
        int kase = 1;
        scanf("%d", &T);
        while (T--) {
            scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &m);
            ll ans = f(b, d) - f(b, c - 1) - f(a - 1, d) + f(a - 1, c - 1);
            ll sum = (b - a + 1) * (d - c + 1);
            ll g = gcd(ans, sum);
            printf("Case #%d: %lld/%lld
    ", kase++, ans / g, sum / g);
        }
    }
    View Code

    当然网上还有数形结合的方法,也是一种角度。

    #pragma warning(disable:4996)#include<iostream>#include<algorithm>#include<bitset>#include<tuple>#include<unordered_map>#include<fstream>#include<iomanip>#include<string>#include<cmath>#include<cstring>#include<vector>#include<map>#include<set>#include<list>#include<queue>#include<stack>#include<sstream>#include<cstdio>#include<ctime>#include<cstdlib>#define pb push_back#define INF 0x3f3f3f3f#define inf 0x7FFFFFFF#define moD 1000000003#define pii pair<ll,ll>#define eps 1e-8#define equals(a,b) (fabs(a-b)<eps)#define bug puts("bug")#define re register#define fi first#define se secondtypedeflonglong ll; typedefunsignedlonglong ull; const ll MOD = 1e6 + 7; constint maxn = 3e5 +5; constdouble Inf = 10000.0; constdouble PI = acos(-1.0); usingnamespacestd; ll a, b, c, d, p, m; ll f(ll a, ll b) { if (a < 0 || b < 0) return0; ll ans = (a / p) * (b / p) * p; ll ma = a % p, mb = b % p; ans += (b / p) * (ma + 1) + (a / p) * (mb + 1); if (ma > m) { ans += min(mb, m) + 1; ll tt = (m - ma + p) % p; if (tt <= mb) ans += mb - tt + 1; } else { ll t = (m - ma + p) % p; if (t <= mb) ans += min(m - t + 1, mb - t + 1); } return ans; } ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); } int main() { int T; int kase = 1; scanf("%d", &T); while (T--) { scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &m); ll ans = f(b, d) - f(b, c - 1) - f(a - 1, d) + f(a - 1, c - 1); ll sum = (b - a + 1) * (d - c + 1); ll g = gcd(ans, sum); printf("Case #%d: %lld/%lld ", kase++, ans / g, sum / g); } }

  • 相关阅读:
    VSCode 设置 CPP 代码风格
    KiCad EDA 5.1.2 使用圆形板框时出现无法走线的问题
    oracle的sql优化
    mybatis 自动生成xml文件配置
    sql循环遍历
    XML
    oracle的concat的用法
    oracle 按某个字段查询重复数据
    Xshell 4的上传与下载
    Oracle之锁
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13394231.html
Copyright © 2020-2023  润新知