Shell Necklace

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 534    Accepted Submission(s): 227

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.

 
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 integer n, meaning the number of shells in this shell necklace, where 1≤n≤105. Following line is a sequence with nnon-negative integer a1,a2,…,an, and ai≤107 meaning the number of schemes to decorate i continuous shells together with a declaration of love.

 
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
3
1 3 7
4
2 2 2 2
0
 
Sample Output
14
54

Hint

For 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
 
题意:
一串由n颗珍珠组成的项链,连续的i个珍珠有ci种染色方式。
问n颗珍珠有多少种染色方式?
题解:
显然可知dp方程
f[i] = sigma(f[i - j] * a[j])
由于n很大,可以考虑分治fft解决。 说说这个分治fft:
如果我们需要计算出l~r的f的值。
假设我们已经计算出(l,mid)的f的值
观察方程
f[i] = sigma(f[j] * a[i - j]) 1 <= j < i
= sigma(f[j] * a[i - j]) + sigma(f[k] * a[i - k]) 1<= j <= mid, mid < k < i
所以可以分开计算f[l~mid]对f[mid+1~r]的影响。
具体过程可以看代码。
使用时记得调整一下下标。

  

 class Complex {
public :
double real, image; Complex(double real = ., double image = .):real(real), image(image) {}
Complex(const Complex &t):real(t.real), image(t.image) {} Complex operator +(const Complex &t) const {
return Complex(real + t.real, image + t.image);
} Complex operator -(const Complex &t) const {
return Complex(real - t.real, image - t.image);
} Complex operator *(const Complex &t) const {
return Complex(real * t.real - image * t.image,
real * t.image + t.real * image);
}
}; const int N = , MOD = ;
const double PI = acos(-.); class FFT {
/**
* 1. Need define PI
* 2. Need define class Complex
* 3. tmp is need for fft, so define a N suffice it
* 4. dig[30] -> (1 << 30) must bigger than N
* */
private :
static Complex tmp[N];
static int revNum[N], dig[]; public :
static void init(int n) {
int len = ;
for(int t = n - ; t; t >>= ) ++len;
for(int i = ; i < n; i++) {
revNum[i] = ;
for(int j = ; j < len; j++) dig[j] = ;
for(int idx = , t = i; t; t >>= ) dig[idx++] = t & ;
for(int j = ; j < len; j++)
revNum[i] = (revNum[i] << ) | dig[j];
}
} static int rev(int x) {
return revNum[x];
} static void fft(Complex a[], int n, int flag) {
/**
* flag = 1 -> DFT
* flag = -1 -> IDFT
* */
for(int i = ; i < n; ++i) tmp[i] = a[rev(i)];
for(int i = ; i < n; ++i) a[i] = tmp[i];
for(int i = ; i <= n; i <<= ) {
Complex wn(cos( * PI / i), flag * sin( * PI / i));
for(int k = , half = i / ; k < n; k += i) {
Complex w(., .);
for(int j = k; j < k + half; ++j) {
Complex x = a[j], y = w * a[j + half];
a[j] = x + y, a[j + half] = x - y;
w = w * wn;
}
}
}
if(flag == -) {
for(int i = ; i < n; ++i) a[i].real /= n;
}
} static void dft(Complex a[], int n) {
fft(a, n, );
} static void idft(Complex a[], int n) {
fft(a, n, -);
}
};
Complex FFT::tmp[N];
int FFT::revNum[N], FFT::dig[]; int n, arr[N];
int f[N];
Complex A[N], B[N]; inline void divideAndConquer(int lef, int rig) {
if(lef >= rig) return;
int mid = (lef + rig) >> ;
divideAndConquer(lef, mid); int m;
for(m = ; m < (rig - lef + ) * ; m <<= );
for(int i = ; i < m; ++i) A[i] = B[i] = Complex();
for(int i = lef; i <= mid; ++i) A[i - lef] = Complex(f[i]);
int len = min(n, m - );
for(int i = ; i < len; ++i) B[i + ] = Complex(arr[i]);
FFT::init(m);
FFT::dft(A, m), FFT::dft(B, m);
for(int i = ; i < m; ++i) A[i] = A[i] * B[i];
FFT::idft(A, m); for(int i = mid + ; i <= rig; ++i)
f[i] = (f[i] + ((ll)(A[i - lef].real + 0.5))) % MOD; divideAndConquer(mid + , rig);
} inline void solve() {
for(int i = ; i < n; ++i) arr[i] %= MOD;
for(int i = ; i <= n; ++i) f[i] = ;
f[] = ;
divideAndConquer(, n); printf("%d\n", f[n]);
} int main() {
while(scanf("%d", &n) == && n) {
for(int i = ; i < n; ++i) scanf("%d", &arr[i]);
solve();
}
return ;
}

2016 Multi-University Training Contest 1 H.Shell Necklace的更多相关文章

  1. 2016 Al-Baath University Training Camp Contest-1 H

     Description You've possibly heard about 'The Endless River'. However, if not, we are introducing it ...

  2. 2016 Al-Baath University Training Camp Contest-1

    2016 Al-Baath University Training Camp Contest-1 A题:http://codeforces.com/gym/101028/problem/A 题意:比赛 ...

  3. 2016 Al-Baath University Training Camp Contest-1 E

    Description ACM-SCPC-2017 is approaching every university is trying to do its best in order to be th ...

  4. 2016 Al-Baath University Training Camp Contest-1 A

    Description Tourist likes competitive programming and he has his own Codeforces account. He particip ...

  5. 2016 Al-Baath University Training Camp Contest-1 J

    Description X is fighting beasts in the forest, in order to have a better chance to survive he's gon ...

  6. 2016 Al-Baath University Training Camp Contest-1 I

    Description It is raining again! Youssef really forgot that there is a chance of rain in March, so h ...

  7. 2016 Al-Baath University Training Camp Contest-1 G

    Description The forces of evil are about to disappear since our hero is now on top on the tower of e ...

  8. 2016 Al-Baath University Training Camp Contest-1 F

    Description Zaid has two words, a of length between 4 and 1000 and b of length 4 exactly. The word a ...

  9. 2016 Al-Baath University Training Camp Contest-1 B

    Description A group of junior programmers are attending an advanced programming camp, where they lea ...

随机推荐

  1. ps你最容易忽略的知识

    了解更多ps知识 1. 快速打开文件­ 双击Photoshop的背景空白处(默认为灰色显示区域)即可打开选择文件的浏览窗口.­ 2. 随意更换画布颜色­ 选择油漆桶工具并按住Shift点击画布边缘,即 ...

  2. Java开发11个过不去的梗

    现在随着编程的普及,作为java程序猿开发的过程逐渐的受到领导的重视,无论自己的经理是能看懂,还是不能看懂,一些事项必须注意起来,不要让自己将来处于不尴不尬的境地,当然这样也方便你我他 1.不在属性文 ...

  3. JS 面向对象随笔

    1.一个对象的静态属性只能通过类名来访问 不能通过实例来访问 如下面定义个HelloWord的类 function HelloWord(){ console.log("这里是HelloWor ...

  4. Html5 杂记

    (一):html5的声明 <!DOCTYPE html> 注意:声明必须是 HTML 文档的第一行,位于 <html> 标签之前.   声明不是 HTML 标签:它是指示 we ...

  5. Android网络操作的几种方法

    安卓开发软件:AndroidStudio 服务器软件:Myeclipse+Tomcat 首先无论是哪种方式,安卓手机软件要想联网,必须要申请联网权限(android.permission.INTERN ...

  6. Linux C 静态库(.a) 与 动态库(.so) 的详解

    库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静态库和动态库的区别 1.静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较 ...

  7. 利用iis虚拟目录实现文件服务器功能(分布式存储)

    要求说明: 通过网站上传文件保存到统一的文件服务器上. 服务器说明: 1.文件服务器以下称为FilesServer,IP地址为:192.168.1.213 2.Web服务器为以下称为WebServer ...

  8. js判断本地是否安装app

    var ua = navigator.userAgent.toLowerCase(); 1.判断是否是微信 function isWeixinBrowser() { return (/micromes ...

  9. mount -t nfs 的使用

    服务安装:1. 在VMware Ubuntu中安装NFS服务: sudo apt-get install nfs-kernel-server2. 安装成功会出现配置文件/etc/exports. ls ...

  10. 使用Java判断字符串中的中文字符数量

    Java判断一个字符串str中中文的个数,经过总结,有以下几种方法(全部经过验证),可根据其原理判断在何种情况下使用哪个方法: 1. char[] c = str.toCharArray(); for ...