【省内训练2018-11-25】Decomposition

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/84563875

【思路要点】

  • 考虑计算每一个数的贡献,即枚举一个数 ii ,计算其在多少划分中出现过。
  • 计算数 ii 在多少划分中出现过可以使用容斥原理。
  • 则有 Ans=i=1Nj=1M(1)j1(Mj)f(Nij,Mj)Ans=\sum_{i=1}^{N}\sum_{j=1}^{M}(-1)^{j-1}\binom{M}{j}f(N-ij,M-j)
  • 其中 f(x,y)f(x,y) 表示将 xx 划分为 yy 个正整数的和的方案数,有 f(x,y)={(x1y1)y0[x=0]y=0f(x,y)=\left\{\begin{array}{rcl}\binom{x-1}{y-1}&&{y\ne0}\\ [x=0]&&{y=0}\end{array} \right.
  • 将上式交换求和顺序,有 Ans=j=1M(1)j1(Mj)i=1Nf(Nij,Mj)Ans=\sum_{j=1}^{M}(-1)^{j-1}\binom{M}{j}\sum_{i=1}^{N}f(N-ij,M-j)
  • 展开 f(x,y)f(x,y) ,有 Ans=[N mod M=0](1)M1+j=1M1(1)j1(Mj)i=1N(Nij1Mj1)Ans=[N\ mod\ M=0]*(-1)^{M-1}+\sum_{j=1}^{M-1}(-1)^{j-1}\binom{M}{j}\sum_{i=1}^{N}\binom{N-ij-1}{M-j-1}
  • 注意到 i=1N(Nij1Mj1)\sum_{i=1}^{N}\binom{N-ij-1}{M-j-1} 形如 i=1N(ai+bc)\sum_{i=1}^{N}\binom{ai+b}{c} ,是一个 cc 次多项式在 11NN 处的点值和,可以表示为一个 c+1c+1 次多项式在 NN 处的点值。
  • 拉格朗日插值即可,注意我们只需求出其在 NN 处的点值,可以在 O(M)O(M) 的时间内完成。
  • 时间复杂度 O(M2)O(M^2)

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 5e6 + 5;
const int P = 998244353;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
ll n; int m;
int fac[MAXN], inv[MAXN];
int power(int x, int y) {
	if (y == 0) return 1;
	int tmp = power(x, y / 2);
	if (y % 2 == 0) return 1ll * tmp * tmp % P;
	else return 1ll * tmp * tmp % P * x % P;
}
void update(int &x, int y) {
	x += y;
	if (x >= P) x -= P;
}
int getc(int x, int y) {
	if (y > x) return 0;
	else return 1ll * fac[x] * inv[y] % P * inv[x - y] % P;
}
void init(int n) {
	fac[0] = 1;
	for (int i = 1; i <= n; i++)
		fac[i] = 1ll * fac[i - 1] * i % P;
	inv[n] = power(fac[n], P - 2);
	for (int i = n - 1; i >= 0; i--)
		inv[i] = inv[i + 1] * (i + 1ll) % P;
}
int getans(ll b, int k, int c) {
	static int val[MAXN];
	ll n = (b - c) / k; b -= (n + 1) * k;
	for (int i = 1; i <= m + 5; i++)
		val[i] = (val[i - 1] + getc(b + i * k, c)) % P;
	if (n <= m + 5) return val[n];
	int ans = 0, x = n % P;
	static int pre[MAXN], suf[MAXN];
	pre[0] = suf[m + 6] = 1;
	for (int i = 1; i <= m + 5; i++)
		pre[i] = 1ll * pre[i - 1] * (x - i + P) % P;
	for (int i = m + 5; i >= 1; i--)
		suf[i] = 1ll * suf[i + 1] * (x - i + P) % P;
	for (int i = 1; i <= m + 5; i++) {
		int coef = 1ll * inv[i - 1] * inv[m + 5 - i] % P;
		if ((m + 5 - i) & 1) coef = (P - coef) % P;
		update(ans, 1ll * val[i] * coef % P * pre[i - 1] % P * suf[i + 1] % P);
	}
	return ans;
}
int main() {
	read(n), read(m);
	init(m * (m + 5));
	int ans = (n % m == 0) * power(P - 1, m - 1);
	for (int i = 1, c = 1; i <= m - 1; i++, c = P - c) {
		int mul = 1ll * c * getc(m, i) % P;
		update(ans, 1ll * mul * getans(n - 1, i, m - i - 1) % P);
	}
	writeln(ans);
	return 0;
}
阅读更多

Necklace Decomposition

07-30

Problem DescriptionnThe set of cyclic rotations of a string are the strings obtained by embedding the string clockwise on a ring, with the first character following on the last, starting at any character position and moving clockwise on the ring until the character preceeding the starting character is reached. A string is a necklace if it is the lexicographically smallest among all its cyclic rotations. For instance, for the string 01011 the cyclic rotations are (10110,01101,11010,10101,01011), and furthermore 01011 is the smallest string and hence, a necklace. nAny string S can be written in a unique way as a concatenation S = T1T2 . . . Tk of necklaces Ti such that Ti+1 < Ti for all i = 1, . . . , k - 1, and TiTi+1 is not a necklace for any i = 1, . . . , k - 1. This representation is called the necklace decomposition of the string S, and your task is to find it. nThe relation < on two strings is the lexicographical order and has the usual interpretation: A < B if A is a proper prefix of B or if A is equal to B in the first j - 1 positions but smaller in the jth position for some j. For instance, 001 < 0010 and 1101011 < 1101100n nnInputnOn the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario consists of one line containing a non-empty string of zeros and ones of length at most 100.n nnOutputnFor each scenario, output one line containing the necklace decomposition of the string. The necklaces should be written as '(' necklace ')'.n nnSample Inputn5n0n0101n0001n0010n11101111011n nnSample Outputn(0)n(0101)n(0001)n(001)(0)n(111)(01111)(011)

没有更多推荐了,返回首页