重温了这道cdq+FFT
讲白了就是不断对 dp[l~mid] 和 sh[1~r] 进行fft 得到 dp[mid+1~r]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int MOD = 313; int N;
int sh[MAXN], dp[MAXN];
int ans;
/****************FFT*************/
int A[MAXN<<2], B[MAXN<<2], C[MAXN<<2];
struct FFTSOLVE {
int pos[MAXN<<2];
struct comp {
double r , i ;
comp ( double _r = 0 , double _i = 0 ) : r ( _r ) , i ( _i ) {}
comp operator + ( const comp& x ) {
return comp ( r + x.r , i + x.i ) ;
}
comp operator - ( const comp& x ) {
return comp ( r - x.r , i - x.i ) ;
}
comp operator * ( const comp& x ) {
return comp ( r * x.r - i * x.i , i * x.r + r * x.i ) ;
}
comp conj () {
return comp ( r , -i ) ;
}
} A[MAXN<<2] , B[MAXN<<2] ;
const double pi = acos ( -1.0 ) ;
void FFT ( comp a[] , int n , int t ) {
for ( int i = 1 ; i < n ; ++ i ) if ( pos[i] > i ) swap ( a[i] , a[pos[i]] ) ;
for ( int d = 0 ; ( 1 << d ) < n ; ++ d ) {
int m = 1 << d , m2 = m << 1 ;
double o = pi * 2 / m2 * t ;
comp _w ( cos ( o ) , sin ( o ) ) ;
for ( int i = 0 ; i < n ; i += m2 ) {
comp w ( 1 , 0 ) ;
for ( int j = 0 ; j < m ; ++ j ) {
comp& A = a[i + j + m] , &B = a[i + j] , t = w * A ;
A = B - t ;
B = B + t ;
w = w * _w ;
}
}
}
if ( t == -1 ) for ( int i = 0 ; i < n ; ++ i ) a[i].r /= n ;
}
void mul ( int *a , int *b , int *c ,int k) {
int i , j ;
for ( i = 0 ; i < k ; ++ i ) A[i] = comp ( a[i] , b[i] ) ;
j = __builtin_ctz ( k ) - 1 ;
for ( int i = 0 ; i < k ; ++ i ) {
pos[i] = pos[i >> 1] >> 1 | ( ( i & 1 ) << j ) ;
}
FFT ( A , k , 1 ) ;
for ( int i = 0 ; i < k ; ++ i ) {
j = ( k - i ) & ( k - 1 ) ;
B[i] = ( A[i] * A[i] - ( A[j] * A[j] ).conj () ) * comp ( 0 , -0.25 ) ;
}
FFT ( B , k , -1 ) ;
for ( int i = 0 ; i < k ; ++ i ) {
c[i] = ( long long ) ( B[i].r + 0.5 );
}
}
}boy;
void cdq(int l,int r) {
if(l == r) {
dp[l] = (dp[l] + sh[l]) % MOD;
return;
}
int mid = (l+r)>>1;
cdq(l,mid); int l1 = 0, l2 = 0;
for(int i = l; i <= mid; ++i) A[l1++] = dp[i];
for(int i = 1; i <= N; ++i) {
if(i+l > r) break;
B[l2++] = sh[i];
}
int len = 1;
while(len < l1*2 || len < l2*2) len <<= 1;
for(int i = l1; i < len; ++i) A[i]=0;
for(int i = l2; i < len; ++i) B[i]=0;
boy.mul(A,B,C,len);
for(int i = mid+1; i <= r; ++i) {
dp[i] = (dp[i]+C[i-l-1]) %MOD;
}
cdq(mid+1,r);
}
int main(){
while(~scanf("%d",&N)) {
memset(dp,0,sizeof(dp));
if(N == 0) break;
for(int i = 1; i <= N; ++i) {
scanf("%d",&sh[i]); sh[i] %= MOD;
} cdq(1,N);
printf("%d\n",dp[N]);
}
return 0;
}

最新文章

  1. SpringBoot常用配置简介
  2. 【叉积】【sdut 2508 图形密码】
  3. Windows 10 Java环境变量配置
  4. C++类的成员函数使用的一些小总结
  5. javascript 函数参数之中的undefined(zz)
  6. VC按钮控件实现指示灯效果
  7. java中的定时器
  8. ASP.NET 后台下载文件方法
  9. 机器学习:Python中如何使用最小二乘法
  10. Redis入门篇
  11. Codeforces 869C The Intriguing Obsession
  12. 开发 | 小程序wx.setScreenBrightness/wx.getScreenBrightness接口测试
  13. R语言学习——图形初阶之折线图与图形参数控制
  14. pyquery 库的方法
  15. HTML前期学习总结
  16. 用canvas画三角形的方法
  17. spring 之 init-method &amp; InitializingBean
  18. Rafy框架
  19. 【Android】Android中不同手机分辨率适配问题
  20. Windows10系统在VMware中安装CentOS7操作系统并实现图形化用户界面Gnome

热门文章

  1. Vim【学习笔记】
  2. IO&amp;&amp;Serize 利用线程Thread.Sleep实现&quot;自动输出&quot;
  3. 2018/2/11 ELK技术栈之ElasticSearch学习笔记二
  4. u-boot核心初始化
  5. javascript 模块
  6. Go语言获取命令行参数
  7. [JSOI2008]最大数maxnumber
  8. Yii小部件
  9. selenium+chrome抓取淘宝搜索抓娃娃关键页面
  10. qml 静态编译程序执行错误 无法定位程序输入点 CreateDXGIFactory2 于动态链接库 dxgi.dll 上