「6月雅礼集训 2017 Day1」看无可看
2017-06-17 20:16
381 查看
【题目大意】
给出n个数,a[1]...a
,称作集合S,求
View Code
【反思】
考场写了60分代码(好像因为数组没开大。。只有40...)
60分的思路还是很好想的
100分要注意到递推的性质用特征根这些来辅助解决。
想到特征根分解后就很容易想到分治FFT了
给出n个数,a[1]...a
,称作集合S,求
# include <math.h> # include <vector> # include <stdio.h> # include <iostream> # include <string.h> # include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; # define RG register # define ST static const int N = 1e5 + 10, M = 2e5 + 10; const int mod = 99991; const double pi = acos(-1.0); inline int getint() { int x = 0, f = 1; char ch = getchar(); while(!isdigit(ch)) { if(ch == '-') f = 0; ch = getchar(); } while(isdigit(ch)) { x = (x<<3) + (x<<1) + ch - '0'; ch = getchar(); } return f ? x : -x; } // x^2 - 2x - 3 = 0 // x1 = -1, x2 = 3 // f(x) = A * (-1)^x + B * 3^x // f(x) = A * (-1)^{a1+a2+...+ak} + B * 3^{a1+a2+...+ak} // f(x) = A * (-1)^{a1} * (-1)^{a2} * ... + B * 3^{a1} * 3^{a2} * ... // (1 + 3^a) ST int n, K, a[M], sr[2][M]; ST int A, B, F0, F1; struct cp { double x, y; cp() {} cp(double x, double y) : x(x), y(y) {} friend cp operator + (cp a, cp b) { return cp(a.x+b.x, a.y+b.y); } friend cp operator - (cp a, cp b) { return cp(a.x-b.x, a.y-b.y); } friend cp operator * (cp a, cp b) { return cp(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x); } }; ST cp u[M], v[M]; inline int pwr(int a, int b) { int ret = 1; while(b) { if(b&1) ret = 1ll * ret * a % mod; a = 1ll * a * a % mod; b >>= 1; } return ret; } ST vector<int> x[M]; # define ls (x<<1) # define rs (x<<1|1) namespace FFT { ST cp w[2][M]; ST int n, lst[M]; inline void init(int _n) { n = 1; while(n < _n) n <<= 1; for (RG int i=0; i<n; ++i) w[0][i] = cp(cos(pi * 2.0 / n * i), sin(pi * 2.0 / n * i)), w[1][i] = cp(w[0][i].x, -w[0][i].y); RG int len = 0; while((1 << len) < n) ++len; for (RG int i=0; i<n; ++i) { int t = 0; for (RG int j=0; j<len; ++j) if(i & (1 << j)) t |= (1 << (len - j - 1)); lst[i] = t; } } inline void DFT(cp *a, int op) { cp *o = w[op]; for (RG int i=0; i<n; ++i) if(i < lst[i]) swap(a[i], a[lst[i]]); for (RG int len=2; len<=n; len <<= 1) { int m = len>>1; for (RG cp *p = a; p != a+n; p += len) { for (RG int k=0; k<m; ++k) { cp t = o[n/len*k] * p[k+m]; p[k+m] = p[k] - t; p[k] = p[k] + t; } } } if(op == 1) for (RG int i=0; i<n; ++i) a[i].x /= (double)n; } inline vector<int> merge(vector<int> a, vector<int> b) { vector<int> ret; ret.clear(); int m = max(a.size(), b.size()) * 2; init(m); // printf("%d\n", n); for (RG int i=0; i<a.size(); ++i) u[i] = cp(a[i], 0.0); for (RG int i=0; i<b.size(); ++i) v[i] = cp(b[i], 0.0); for (RG int i=a.size(); i<n; ++i) u[i] = cp(0.0, 0.0); for (RG int i=b.size(); i<n; ++i) v[i] = cp(0.0, 0.0); DFT(u, 0); DFT(v, 0); for (RG int i=0; i<n; ++i) u[i] = u[i] * v[i]; DFT(u, 1); for (RG int i=0; i<K+1 && i<m; ++i) ret.push_back(((ll)(u[i].x + 0.5)) % mod); return ret; } } int id; inline void solve(int x, int l, int r) { if(l == r) { p[x].clear(); p[x].push_back(1), p[x].push_back(sr[id][l]); return ; } RG int mid = l+r>>1; solve(ls, l, mid); solve(rs, mid+1, r); p[x] = FFT::merge(p[ls], p[rs]); // printf("l = %d, r = %d\n", l, r); // for (int i=0; i<p[x].size(); ++i) printf("%d ", p[x][i]); // puts(""); } # include <time.h> int main() { // freopen("see.in", "r", stdin); // freopen("see.out", "w", stdout); int beg = clock(); n = getint(), K = getint(); for (RG int i=1; i<=n; ++i) { a[i] = getint(); sr[0][i] = pwr(3, a[i]); sr[1][i] = pwr(mod-1, a[i]); } F0 = getint(), F1 = getint(); B = 1ll * (F0 + F1) * pwr(4, mod-2) % mod; A = (F0 - B + mod) % mod; id = 0; solve(1, 1, n); int t = 1ll * B * p[1][K] % mod; id = 1; solve(1, 1, n); t += 1ll * A * p[1][K] % mod; if(t >= mod) t -= mod; printf("%d\n", t); int end = clock() - beg; cerr << end << " ms" << endl; return 0; }
View Code
【反思】
考场写了60分代码(好像因为数组没开大。。只有40...)
60分的思路还是很好想的
100分要注意到递推的性质用特征根这些来辅助解决。
想到特征根分解后就很容易想到分治FFT了
相关文章推荐
- 「6月雅礼集训 2017 Day1」说无可说
- 「6月雅礼集训 2017 Day5」吃干饭
- 「6月雅礼集训 2017 Day5」学外语
- 「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)
- #6029. 「雅礼集训 2017 Day1」市场--线段树区间更新
- 「6月雅礼集训 2017 Day2」B
- 「6月雅礼集训 2017 Day7」回转寿司
- 「6月雅礼集训 2017 Day8」infection
- [线段树][简单复杂度分析]LOJ#6029. 「雅礼集训 2017 Day1」市场
- 「6月雅礼集训 2017 Day5」仰望星空
- loj6029 「雅礼集训 2017 Day1」市场
- #6029. 【雅礼集训 2017 Day1】市场
- 「6月雅礼集训 2017 Day2」C
- 「6月雅礼集训 2017 Day4」寻找天哥
- 「6月雅礼集训 2017 Day7」三明治
- 「6月雅礼集训 2017 Day8」gcd
- #6030. 【雅礼集训 2017 Day1】矩阵
- [后缀自动机 阈值] LOJ#6031. 「雅礼集训 2017 Day1」字符串
- 「6月雅礼集训 2017 Day7」电报
- 「6月雅礼集训 2017 Day8」route