【HDU5730 2016 Multi-University Training Contest 1H】【FFT + cdq 分治】 Shell Necklace f[i]=∑f[i-j] x a[j]
来源:互联网 发布:武当七侠java 编辑:程序博客网 时间:2024/05/21 06:59
Shell Necklace
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 290 Accepted Submission(s): 116
Problem Description
Perhaps the sea‘s definition of a shell is the pearl. However, in my view, a shell necklace with n beautiful shells contains the most sincere feeling for my best lover Arrietty, but even that is not enough.
Suppose the shell necklace is a sequence of shells (not a chain end to end). Considering i continuous shells in the shell necklace, I know that there exist different schemes to decorate the i shells together with one declaration of love.
I want to decorate all the shells with some declarations of love and decorate each shell just one time. As a problem, I want to know the total number of schemes.
Suppose the shell necklace is a sequence of shells (not a chain end to end). Considering i continuous shells in the shell necklace, I know that there exist different schemes to decorate the i shells together with one declaration of love.
I want to decorate all the shells with some declarations of love and decorate each shell just one time. As a problem, I want to know the total number of schemes.
Input
There are multiple test cases(no more than 20 cases and no more than 1 in extreme case), ended by 0.
For each test cases, the first line contains an integern , meaning the number of shells in this shell necklace, where 1≤n≤105 . Following line is a sequence with n non-negative integer a1,a2,…,an , and ai≤107 meaning the number of schemes to decorate i continuous shells together with a declaration of love.
For each test cases, the first line contains an integer
Output
For each test case, print one line containing the total number of schemes module 313 (Three hundred and thirteen implies the march 13th, a special and purposeful day).
Sample Input
31 3 742 2 2 2 0
Sample Output
1454HintFor the first test case in Sample Input, the Figure 1 provides all schemes about it. The total number of schemes is 1 + 3 + 3 + 7 = 14.
Author
HIT
Source
2016 Multi-University Training Contest 1
#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;typedef double ld;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }const int N = 1 << 17, Z = 313, ms63 = 0x3f3f3f3f;const double PI = acos(-1.0);struct Complex{double r, i;Complex(double r = 0, double i = 0) : r(r), i(i) {}Complex operator + (const Complex& t) const { return Complex(r + t.r, i + t.i); }Complex operator - (const Complex& t) const { return Complex(r - t.r, i - t.i); }Complex operator * (const Complex& t) const { return Complex(r * t.r - i * t.i, r * t.i + i * t.r); }}X[N], Y[N];void FFT(Complex y[], int n, int rev)//rev == 1时为DFT,rev == -1时为IDFT{for (int i = 1, j, k, t; i < n; ++i){for (j = 0, k = n >> 1, t = i; k; k >>= 1, t >>= 1) j = j << 1 | t & 1;if (i < j) swap(y[i], y[j]);}for (int s = 2, ds = 1; s <= n; ds = s, s <<= 1){Complex wn(cos(rev * 2 * PI / s), sin(rev * 2 * PI / s));for (int k = 0; k < n; k += s){Complex w(1, 0), t;for (int i = k; i < k + ds; ++i){y[i + ds] = y[i] - (t = w * y[i + ds]);y[i] = y[i] + t;w = w * wn;}}}if (rev == -1) for (int i = 0; i < n; ++i) y[i].r /= n;}int n, a[N], f[N];void cdq(int l, int r){if (l == r) { f[l] = (f[l] + a[l]) % Z; return; }int mid = l + r >> 1;cdq(l, mid);int len1 = mid - l + 1;int len2 = r - l + 1;int len = 1; while (len < len2) len <<= 1;//这里的数组大小应该是while(len < len1 + len2)for (int i = 0; i < len1; ++i) X[i] = Complex(f[l + i], 0);for (int i = len1; i < len; ++i) X[i] = Complex(0, 0);for (int i = 0; i < len2; ++i) Y[i] = Complex(a[i], 0);for (int i = len2; i < len; ++i) Y[i] = Complex(0, 0);FFT(X, len, 1);FFT(Y, len, 1);for (int i = 0; i < len; ++i) Y[i] = X[i] * Y[i];FFT(Y, len, -1);for (int i = mid + 1; i <= r; ++i)f[i] = f[i] + (int)(Y[i - l].r + 0.5) % Z;cdq(mid + 1, r);}int main(){while (~scanf("%d", &n), n){MS(f, 0);for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), a[i] %= Z;cdq(1, n);printf("%d\n", f[n]);}return 0;}/*【trick&&吐槽】在本题,我们做FFT多项式乘法的时候,X*Y的目标数组的长度要开多少呢?按照正常的乘法逻辑,我们要把数组开到len1+len2.然而,这道题我们只需要使用到len1【题意】有n(1e5)个数a[],a[i]都是[1e7]范围的数。f[1]=0;f[i]=∑(f[i - j] * a[j]), j∈[1, i];让你求f[n] % Z【类型】fft + cdq分治【分析】这道题我们不能做n次fft,会重复计算,最终导致TLE。我们采取cdq分治的方式做加速。所谓cdq分治,利用了这道题目中的——想求f[i],需要加进所有f[j,j<i]对f[i]的贡献我们把区间分成了以下两块[l,mid] [mid+1,r],我们先处理[l,mid],然后把[l,mid]的影响向[mid+1,r]转移,再去处理[mid+1,r]。问题是,如何做转移呢?fft。回归fft如何做大数相乘运算v[0] v[1] v[2]u[0] u[1] u[2]我们乘出来之后变成了——(0*0) (0*1+1*0) (0*2+1*1*2*0) (1*2+2*1) (2*2)显然,有一侧为f[l],f[l+1],f[l+2],f[l+3],...,f[mid-1],f[mid]另一侧为a[0],a[1],a[2],...,a[mid-l]我们乘起来就变成了——(f[l] * a[0]) =不需要的数...(f[l] * a[mid+1-l] + f[l+1] * a[mid+1-l-1] + ...) = f[mid+1]...即,我们需要f[l]~f[mid]中的每个数同时需要a[0]~a[r-l]中的每个数然后FFT就可以得到结果【时间复杂度&&优化】尽管我们做了nlogn次FFT但是事实上相当于只做了logn层长度为n的FFT总的复杂度为O(nlognlogn),可以无压力AC这道题的数组我们要开多大呢?100000的上log 1<<17即可*/
0 0
- 【HDU5730 2016 Multi-University Training Contest 1H】【FFT + cdq 分治】 Shell Necklace f[i]=∑f[i-j] x a[j]
- China Northeast Multi-University Training Contest I J - Remoteland
- [DP] [1D1D优化] [FFT] [CDQ分治] [HDU5730] Shell Necklace
- 【HDU5730】Shell Necklace——CDQ+FFT
- 2014 Multi-University Training Contest 1 - J Rating
- hdu 5730 2016 Multi-University Training Contest 1 Shell Necklace 解题报告
- 2016 Multi-University Training Contest 1 1005 Necklace
- China Northeast Multi-University Training Contest I
- 【HDU5739 2016 Multi-University Training Contest 2F】【cdq分治+并查集做法 or 点双连通做法】Fantasia 每点删除后联通块权值和的积
- 2013 Multi-University Training Contest 1 I-number 大数
- 2013 Multi-University Training Contest 1——I-number
- 2012 Multi-University Training Contest 5 Problem F Permutation(HDU4345)
- 【HDU5732 2016 Multi-University Training Contest 1J】【树哈希模板 无根树的同构】Subway 对应两棵树的匹配关系
- HDU 4870 Rating 2014 Multi-University Training Contest 1 J题 概率DP+高斯消元
- 利用线程的知识,要求打印的结果为:1 2 A 3 4 B 5 6 C 7 8 D 9 10 11 12 ... 52 E F G H I J K ... X Y Z
- HDU 5730 多校1 Shell Necklace (CDQ分治+FFT)
- hdu 5730 Shell Necklace cdq分治+FFT
- [HDU5739] Fantasia [2016 Multi-University Training Contest 2(多校联合训练2) F]
- 算法导论之B树
- iOS 探讨之 静态库联调
- Matlab、C++、OpenCV混合编程
- cygwin下如何清屏(clear screnn)
- android 文件读取(assets)
- 【HDU5730 2016 Multi-University Training Contest 1H】【FFT + cdq 分治】 Shell Necklace f[i]=∑f[i-j] x a[j]
- 进阶项目1.2递归函数.公约数
- 嗖嗖嗖
- 常用RGB颜色表 色值
- H5中级进阶-多屏互动
- IO_Homework1~2 打印九九乘法表 复制文件
- java中三元运算符
- 打印各种图案
- 优化Java堆大小的5个技巧