Educational Codeforces Round 148 E. Combinatorics Problem 【组合数公式DP】
个人练习记录
E. Combinatorics Problem
题意
给出 n , a 1 , x , y , m n,a_1,x,y,m n,a1,x,y,m, ∀ i ∈ [ 2 , n ] , a i = ( a i − 1 ⋅ x + y ) m o d m \forall i \in [2,n],a_i = (a_{i - 1} \cdot x + y) mod \hspace{4pt}m ∀i∈[2,n],ai=(ai−1⋅x+y)modm
对于每一个 b i b_i bi,则由题中所给公式求出
输出 b 1 ⋅ 1 ⨁ b 2 ⋅ 2 ⨁ b 3 ⋅ 3..... ⨁ b n ⋅ n b_1 \cdot 1 \bigoplus b_2 \cdot 2 \bigoplus b_3 \cdot 3 ..... \bigoplus b_n \cdot n b1⋅1⨁b2⋅2⨁b3⋅3.....⨁bn⋅n
思路
先线性求出数组 a a a,然后我们观察 b i b_i bi 公式:
- b i = C i k ⋅ a 1 + C i − 1 k ⋅ a 2 + C i − 2 k ⋅ a 3 + . . . + C 1 k ⋅ a i b_i = C_i ^ k \cdot a_1 + C_{i - 1} ^ k \cdot a_2 + C_{i - 2} ^ k \cdot a_3 +...+ C_1^k \cdot a_i bi=Cik⋅a1+Ci−1k⋅a2+Ci−2k⋅a3+...+C1k⋅ai
由组合数公式: C n m = C n − 1 m − 1 + C n − 1 m C_n^m = C_{n - 1}^{m - 1} + C_{n - 1}^m Cnm=Cn−1m−1+Cn−1m,我们可以得到:
b i = ( C i − 1 k − 1 + C i − 1 k ) ⋅ a 1 + ( C i − 2 k − 1 + C i − 2 k ) ⋅ a 2 + ( C i − 3 k − 1 + C i − 3 k ) ⋅ a 3 + . . . + C 1 k ⋅ a i b_i = (C_{i - 1} ^ {k - 1} + C_{i - 1} ^ k) \cdot a_1 + (C_{i - 2} ^ {k - 1} + C_{i - 2} ^ k)\cdot a_2 + (C_{i - 3} ^ {k - 1} + C_{i - 3} ^ k )\cdot a_3 +...+ C_1^k \cdot a_i bi=(Ci−1k−1+Ci−1k)⋅a1+(Ci−2k−1+Ci−2k)⋅a2+(Ci−3k−1+Ci−3k)⋅a3+...+C1k⋅ai
用 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示当 k = j k = j k=j 时, b i b_i bi 的值,那么我们可以得出除了最后一项 C 1 k ⋅ a 1 C_1^k \cdot a_1 C1k⋅a1 外,其他每一项的第一项合并在一起就是: d p [ i − 1 ] [ k − 1 ] dp[i - 1][k - 1] dp[i−1][k−1],第二项合并在一起就是: d p [ i − 1 ] [ k ] dp[i - 1][k] dp[i−1][k]
那么我们有递推公式: d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + d p [ i − 1 ] [ j ] + C 1 k ⋅ a i dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] + C_1^k \cdot a_i dp[i][j]=dp[i−1][j−1]+dp[i−1][j]+C1k⋅ai
特别地,当 k = 0 k = 0 k=0 时,所有 C i 0 = 1 C_i ^ 0 = 1 Ci0=1,因此 d p [ i ] [ 0 ] dp[i][0] dp[i][0] 是 ∑ i = 1 i a i \sum_{i = 1}^{i} a_i ∑i=1iai 这个前缀和
时间复杂度: O ( n k ) O(nk) O(nk)
#include<bits/stdc++.h>
#define fore(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;
const int INF=0x3f3f3f3f;
const long long INFLL=1e18;
typedef long long ll;
template<class T>
constexpr T power(T a, ll b){
T res = 1;
while(b){
if(b&1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
constexpr ll mul(ll a,ll b,ll mod){ //快速乘,避免两个long long相乘取模溢出
ll res = a * b - ll(1.L * a * b / mod) * mod;
res %= mod;
if(res < 0) res += mod; //误差
return res;
}
template<ll P>
struct MLL{
ll x;
constexpr MLL() = default;
constexpr MLL(ll x) : x(norm(x % getMod())) {}
static ll Mod;
constexpr static ll getMod(){
if(P > 0) return P;
return Mod;
}
constexpr static void setMod(int _Mod){
Mod = _Mod;
}
constexpr ll norm(ll x) const{
if(x < 0){
x += getMod();
}
if(x >= getMod()){
x -= getMod();
}
return x;
}
constexpr ll val() const{
return x;
}
explicit constexpr operator ll() const{
return x; //将结构体显示转换为ll类型: ll res = static_cast<ll>(OBJ)
}
constexpr MLL operator -() const{ //负号,等价于加上Mod
MLL res;
res.x = norm(getMod() - x);
return res;
}
constexpr MLL inv() const{
assert(x != 0);
return power(*this, getMod() - 2); //用费马小定理求逆
}
constexpr MLL& operator *= (MLL rhs) & { //& 表示“this”指针不能指向一个临时对象或const对象
x = mul(x, rhs.x, getMod()); //该函数只能被一个左值调用
return *this;
}
constexpr MLL& operator += (MLL rhs) & {
x = norm(x + rhs.x);
return *this;
}
constexpr MLL& operator -= (MLL rhs) & {
x = norm(x - rhs.x);
return *this;
}
constexpr MLL& operator /= (MLL rhs) & {
return *this *= rhs.inv();
}
friend constexpr MLL operator * (MLL lhs, MLL rhs){
MLL res = lhs;
res *= rhs;
return res;
}
friend constexpr MLL operator + (MLL lhs, MLL rhs){
MLL res = lhs;
res += rhs;
return res;
}
friend constexpr MLL operator - (MLL lhs, MLL rhs){
MLL res = lhs;
res -= rhs;
return res;
}
friend constexpr MLL operator / (MLL lhs, MLL rhs){
MLL res = lhs;
res /= rhs;
return res;
}
friend constexpr std::istream& operator >> (std::istream& is, MLL& a){
ll v;
is >> v;
a = MLL(v);
return is;
}
friend constexpr std::ostream& operator << (std::ostream& os, MLL& a){
return os << a.val();
}
friend constexpr bool operator == (MLL lhs, MLL rhs){
return lhs.val() == rhs.val();
}
friend constexpr bool operator != (MLL lhs, MLL rhs){
return lhs.val() != rhs.val();
}
};
const ll mod = 998244353;
using Z = MLL<mod>;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n;
ll a1, x, y, m, k;
std::cin >> n >> a1 >> x >> y >> m >> k;
std::vector<ll> a(n + 1);
a[1] = a1;
fore(i, 2, n + 1) a[i] = (a[i - 1] * x % m + y) % m;
std::vector<std::vector<Z>> dp(n + 1, std::vector<Z>(k + 1, 0));
fore(i, 1, n + 1) dp[i][0] = dp[i - 1][0] + a[i];
fore(j, 1, k + 1)
fore(i, 1, n + 1)
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] + (j <= 1) * a[i];
ll ans = 0;
fore(i, 1, n + 1) ans ^= (1ll * i * dp[i][k].x);
std::cout << ans;
return 0;
}
更多推荐
所有评论(0)