首页 > 其他分享 >高橋君 题解

高橋君 题解

时间:2023-10-04 20:34:24浏览次数:30  
标签:nowM nowN dbinom 高橋 题解 valueType Ans mod

AtCoder 天下一プログラマーコンテスト2014 本戦 高橋君

题意

给定 \(n, k\),求

\[\sum\limits_{i = 0}^{k}\dbinom{n}{i} \]

多测,\(1 \le n, k, T \le 10^5\)。

题解

可以考虑使用莫队求解,下文讲述如何移动指针。

\(n \rightarrow n + 1\)

根据杨辉三角递推式 \(\dbinom{n}{m} = \dbinom{n - 1}{m} + \dbinom{n - 1}{m - 1}\) 可以得出

\[\begin{aligned} F(n + 1, m) &= \sum\limits_{i = 0}^{m} \dbinom{n + 1}{i} \\ &= \sum\limits_{i = 0}^{m} \left(\dbinom{n}{i} + \dbinom{n}{i - 1}\right) \\ &= 2\sum\limits_{i = 0}^{m} \dbinom{n}{i} - \dbinom{n}{m} \\ &= 2 \cdot F(n, m) - \dbinom{n}{m} \end{aligned}\]

\(m \rightarrow m + 1\)

\[\begin{aligned} F(n, m + 1) &= \sum\limits_{i = 0}^{m + 1} \dbinom{n}{i} \\ &= \sum\limits_{i = 0}^{m} \dbinom{n}{i} + \dbinom{n}{m + 1}\\ &= F(n, m) + \dbinom{n}{m + 1} \end{aligned}\]

这部分的复杂度为 \(\mathcal{O}(n \sqrt{n})\)。

总复杂度 \(\mathcal{O}(n \sqrt{n})\),可以通过本题。

Code

#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef ValueVector::iterator iterator;
typedef std::vector<iterator> IteratorVector;

constexpr valueType MOD = 1e9 + 7;

template<typename T1, typename T2, typename T3 = valueType>
void Inc(T1 &a, T2 b, const T3 &mod = MOD) {
    a = a + b;

    if (a >= mod)
        a -= mod;
}

template<typename T1, typename T2, typename T3 = valueType>
void Dec(T1 &a, T2 b, const T3 &mod = MOD) {
    a = a - b;

    if (a < 0)
        a += mod;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 mul(T1 a, T2 b, const T3 &mod = MOD) {
    return (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
void Mul(T1 &a, T2 b, const T3 &mod = MOD) {
    a = (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 pow(T1 a, T2 b, const T3 &mod = MOD) {
    T1 result = 1;

    while (b > 0) {
        if (b & 1)
            Mul(result, a, mod);

        Mul(a, a, mod);
        b = b >> 1;
    }

    return result;
}

namespace UU {
    valueType N, M;

    ValueVector Fact, InvFact, belong, ans;

    valueType C(valueType n, valueType m) {
        if (n < m)
            return 0;

        return mul(Fact[n], mul(InvFact[m], InvFact[n - m]));
    }

    struct Query {
        valueType n, m, id;

        Query(valueType n, valueType m, valueType id) : n(n), m(m), id(id) {}

        friend bool operator<(Query const &left, Query const &right) {
            if (belong[left.n] != belong[right.n])
                return belong[left.n] < belong[right.n];

            return left.m < right.m;
        }
    };

    std::vector<Query> query;

    void init(valueType n) {
        N = n;
        M = 0;

        Fact.resize(N + 1);
        InvFact.resize(N + 1);
        belong.resize(N + 1);

        valueType block = std::ceil(std::sqrt((double) N));

        for (valueType i = 1; i <= N; ++i)
            belong[i] = (i - 1) / block + 1;

        Fact[0] = 1;
        for (valueType i = 1; i <= N; ++i)
            Fact[i] = mul(Fact[i - 1], i);

        InvFact[N] = pow(Fact[N], MOD - 2);
        for (valueType i = N - 1; i >= 0; --i)
            InvFact[i] = mul(InvFact[i + 1], i + 1);
    }

    void add(valueType id, valueType n, valueType m) {
        query.emplace_back(n, m, id);
    }

    constexpr valueType Inv2 = (MOD + 1) / 2;

    void solve() {
        std::sort(query.begin(), query.end());

        M = (valueType) query.size();
        ans.resize(M);

        valueType nowN = 0, nowM = 0;
        valueType Ans = 1;

        for (auto const &iter : query) {
            while (nowM < iter.m) {
                ++nowM;

                Inc(Ans, C(nowN, nowM));
            }

            while (nowM > iter.m) {
                Dec(Ans, C(nowN, nowM));

                --nowM;
            }

            while (nowN < iter.n) {
                Mul(Ans, 2);
                Dec(Ans, C(nowN, nowM));

                ++nowN;
            }

            while (nowN > iter.n) {
                --nowN;

                Inc(Ans, C(nowN, nowM));
                Mul(Ans, Inv2);
            }

            ans[iter.id] = Ans;
        }
    }

    void output() {
        for (auto const &iter : ans)
            std::cout << iter << std::endl;
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    valueType M;

    std::cin >> M;

    UU::init(1e5);

    for (valueType i = 0; i < M; ++i) {
        valueType n, m;

        std::cin >> n >> m;

        UU::add(i, n, m);
    }

    UU::solve();

    UU::output();

    return 0;
}

标签:nowM,nowN,dbinom,高橋,题解,valueType,Ans,mod
From: https://www.cnblogs.com/User-Unauthorized/p/solution-AT_tenka1_2014_final_d.html

相关文章

  • 题解 P2674 《瞿葩的数字游戏》T2-多边形数
    题目描述给你一个正整数数\(n\),问你它是不是多边形数\(K\),如果是,设\(K_1\)是最小的\(K\),\(K_2\)是次小的\(K\),输出\(K_1\)和\(K_2\)。具体思路我们主要来看上面这张表里有什么规律。性质1:\(1\)是任何一个多边形数。性质2:\(2\)不是任何一个多边形数。性......
  • 情报破译 题解
    \(d<n\le2e5,m\le10,1\lep\le10^9,0\lea_i\le1e9\)每个位运算之间独立,所以我们可以构造一个\(\{2^{k-1},2^{k-1}.....\}\)和一个\(\{0,0,0...\}\)的数组,让他们倍增去做如上运算,最后用他们把\(p\)轮拼出来,我们就知道了\(i\)位置上二进制下第\(j\)位如果是\(0\)......
  • 国标GB28181协议下视频监控平台EasyGBS播放器起播慢或延迟高问题解决方案
    GB28181视频监控国标平台EasyGBS是基于国标GB28181协议、支持多路设备同时接入的视频监控/视频云服务平台,支持对多平台、多终端分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。国标GB28181平台EasyGBS可提供视频直播监控、云端录像、云存储、检索回放、智能告警、语音对讲、平......
  • P1025 [NOIP2001 提高组] 数的划分 题解
    题目传送门本题共有两种方法,分别是递归深搜和动态规划方法一:递归深搜Solution从小到大一一枚举每一个划分的数,。只要找到一种方案就记录,具体细节代码中有注释。Code#include<bits/stdc++.h>usingnamespacestd;intn,k,ans;voiddfs(intstart,intstep,intsum){......
  • 【题解】Typo
    TypoDescreption求反转一个不合法的括号序列中的一位使其成为一个合法序列的方案数(保证方案一定存在)Solution其实也就是一道较复杂的模拟题先判断哪一类括号数量更多,因为一定是将数量多的括号改成数量少的才有可能变为合法序列,这里就先用左括号举例记录每个位置时没有配对的......
  • CF1234(Div. 3) 题解(A to E)
    AEqualizePricesAgain题解题目大意\(n\)个商品,每个商品价格为\(a_i\),求一个最小的价格\(x\),使得不亏本(即\(\sum\limits_{i=1}^n{(a_i-x)}\ge0\))。解题思路输出平均数向上取整(即\(\left\lceil(\sum\limits_{i=1}^n{a_i})\divn\right\rceil\))即可。代码#include<bit......
  • 项链 题解
    随机化写法很强,但是这里不说。这里只记录数据结构写法。枚举右端点,快速找左端点。首先一种合法的方案中,一种颜色只会有两种情况。全部在区间中及全部在区间外。对于区间外的情况,也就是最后一次出现的位置\(p\)大于右端点\(r\),我们可以维护当前枚举右端点之前的所有颜色非......
  • CF1203(Div. 3) 题解(C to F1)
    由于太懒了,所以不想(会)写\(\texttt{AB}\)和\(\texttt{F2}\)。CCommonDivisors题解题目大意给定一个长度为\(n\)的数列\(\{a_i\}\),求\(\sigma(\gcd\limits_{i\in[1,n]}\{a_i\})\)。解题思路先算出所有元素的最大公因数,如果最大公因数\(g\)为\(1\),即所有元素两两......
  • CF1873(Div. 4) 题解 (A to E)
    AShortSort题解题目大意给定一个长度为\(3\)、由\(a,b,c\)组成的字符串,问可以不变或交换两个字符是的变为\(\texttt{abc}\)。解题思路由于大小固定,所以预处理可行的字符串(仅包含\(\texttt{abcacbbaccba}\))即可。代码#include<bits/stdc++.h>usingnamespacest......
  • 题解 CF1034C【Region Separation】/ SS221116D【Xiong AK 10 IOI】
    很妙的性质题!全是意识流证明见过吗?problem每次选一个非空边集删掉,谓之曰砍树。砍树后需要满足每个连通块的点权和相同。在一个方案中可以砍很多次树,都要满足砍树后的要求。一共有多少种合法方案呢?\(n\leq10^6,1\leqa_i\leq10^9\)。solution假如我们将树砍成\(k\)个连通......