zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 104 D(卡常)

    考虑对每个x计算答案.

    将除x以外的数都减去x,答案就是这些数的多重集(可以为空)和为0的方案数乘上(K+1), 最后加一个 k个 x

    然而, t了6个点(别走Ψ( ̄∀ ̄)Ψ)

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    typedef vector<int> VI;
    typedef double db;
    
    template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
    template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
    template<class T> void clear(T& a) { T().swap(a); }
    
    const int N = 1e2 + 5, M = 1e6 + 5;
    
    int n, m, _, k;
    ll f1[M], f2[M];
    
    int main() {
        IOS; cin >> n >> k >> m;
        VI ans; f1[0] = f2[0] = 1;
        rep(i, 1, (n + 1) >> 1) {
            int l = (i - 1) * i / 2 * k, r = (n - i + 1) * (n - i) / 2 * k;
            rep(j, 1, l) f1[j] = 0;
            rep(j, 1, r) f2[j] = 0;
            rep(j, 1, i - 1) {
                int r = (j - 1) * j / 2 * k, d = j * k;
                rep(s, j, r) f1[s] = (f1[s] + f1[s - j]) % m;
                per(s, r, d + j) f1[s] = (f1[s] + m - f1[s - d - j]) % m;
            }
            rep(j, 1, n - i) {
                int r = (j - 1) * j / 2 * k, d = j * k;
                rep(s, j, r) f2[s] = (f2[s] + f2[s - j]) % m;
                per(s, r, d + j) f2[s] = (f2[s] + m - f2[s - d - j]) % m;
            }
            ll res = k;
            per(s, min(l, r), 1) res = (res + f1[s] * f2[s] % m * (k + 1) % m) % m;
            ans.pb(res);
        }
        for (auto i : ans) cout << i << '
    ';
        per(i, ans.size() - 1 - (n & 1), 0) cout << ans[i] << '
    ';
        return 0;
    }
    

    然而还可以优化, 思路是一样的, 直接把左右区间写成一个区间, 偏移量嘛

    假定把 x 左边全部选上,也就是现在是最小值, 左区间全部-x(都是负数), 对于1~N(除了x), 选择 1~x-1, 相当于把最开始选择左区间的数扔掉了, ++a, 选择右区间, 也是 ++a是不是少了一个常数啊?

    //对于 1e8小个常数是优化是相当高的

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    typedef vector<int> VI;
    typedef double db;
    
    template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
    template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
    template<class T> void clear(T& a) { T().swap(a); }
    
    const int N = 1e2 + 5, M = 1e6;
    
    int n, m, _, k;
    int a[M << 1], *f;
    
    void add(int& x, int y){
        x += y;
        if(x >= m) x -= m;
    }
    
    void sub(int& x, int y){
        x -= y;
        if(x < 0) x += m;
    }
    
    int main() {
        IOS; cin >> n >> k >> m;
        VI ans; f = a + M;
        rep(i, 1, (n + 1) >> 1) {
            int l = -(i - 1) * i / 2 * k, r = (n - i + 1) * (n - i) / 2 * k;
            rep(j, l, r) f[j] = 0; f[l] = 1; //左区间全选
            
            VI res;
            rep(j, 1, n) if (i != j) res.pb(abs(j - i)); //都是++a
            sort(all(res)); r = l;
            
            for (int x : res) {
                int d = x * k; r += d;
                rep(j, l + x, r) add(f[j], f[j - x]);
                per(j, r, l + x + d) sub(f[j], f[j - d - x]);
            }
            ans.pb(((ll)f[0] * (k + 1) - 1 + m) % m);
        }
        rep(i, (n + 1 >> 1) + 1, n) ans.pb(ans[n - i]);
        for (int i : ans) cout << i << '
    ';
        return 0;
    }
    
    
  • 相关阅读:
    sql server 阻塞与锁
    JVM监控
    Java性能分析之线程栈详解与性能分析
    MySQL监控调优
    JVM(上)
    性能测试流程介绍
    性能测试分析调优思路
    监控分析——Web中间件
    Linux性能测试工具安装全集
    Java基础(二十)集合(2)Collection接口
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13767505.html
Copyright © 2011-2022 走看看