FFT与多项式、生成函数题目泛做
题目1 COGS 很强的乘法问题
高精度乘法用FFT加速
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#define Pi acos(-1) using namespace std;
const int N = + ;
const int rad = ; struct Complex {
double r, i;
Complex(double x = , double y = ) { r = x; i = y; }
Complex operator + (Complex x) { return Complex(r + x.r, i + x.i); }
Complex operator - (Complex x) { return Complex(r - x.r, i - x.i); }
Complex operator * (Complex x) { return Complex(r * x. r - i * x.i, r * x.i + i * x.r); }
}a[N], b[N];; int n, m, l, r[N], c[N];
char ss[N]; void dft(Complex *s, int f) {
for(int i = ; i < n; ++ i)
if(i < r[i]) swap(s[i], s[r[i]]);
for(int i = ; i < n; i <<= ) {
Complex wn(cos(Pi / i), f * sin(Pi / i));
for(int j = ; j < n; j += (i << )) {
Complex w(, );
for(int k = ; k < i; ++ k) {
Complex x = s[j + k], y = w * s[j + k + i];
s[j + k] = x + y;
s[j + k + i] = x - y;
w = w * wn;
}
}
}
if(f == -)
for(int i = ; i < n; ++ i)
s[i].r /= n;
} int main() {
#ifndef stone
freopen("bettermul.in", "r", stdin);
freopen("bettermul.out", "w", stdout);
#endif int len1, len2;
scanf("%s", ss); len1 = strlen(ss);
for(int i = ; i < len1; ++ i) a[i] = ss[len1 - i - ] - '';
scanf("%s", ss); len2 = strlen(ss);
for(int i = ; i < len2; ++ i) b[i] = ss[len2 - i - ] - '';
n = max(len1, len2); m = (n << ) - ;
for(n = ; n <= m; n <<= ) l ++;
for(int i = ; i < n; ++ i)
r[i] = (r[i >> ] >> ) | ((i & ) << (l - ));
dft(a, ); dft(b, );
for(int i = ; i < n; ++ i) a[i] = a[i] * b[i];
dft(a, -);
for(int i = ; i <= m; ++ i) c[i] = (int) (a[i].r + 0.5);
for(int i = ; i <= m; ++ i) {
if(c[i] >= rad) {
c[i + ] += c[i] / rad;
c[i] %= rad;
if(i == m) m ++;
}
}
int pos = m;
while(c[pos] == ) -- pos;
for(int i = pos; i >= ; -- i) printf("%d", c[i]); #ifndef stone
fclose(stdin); fclose(stdout);
#endif
return ;
}
COGS
题目2 BZOJ4259 残缺的字符串
算法讨论:(摘自Claris的博客,写得很清楚,我就是看这个才会做的)
注意:如果开第二个字符串的倍长的话,FFT会超时。还要注意统计答案的区间是什么。不要错了。
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath> using namespace std;
typedef long long ll;
const int N = + ;
#define Pi acos(-1) struct Cp {
double r, i;
Cp(double _r = , double _i = ):
r(_r), i(_i) {}
Cp operator + (Cp x) {
return Cp(r + x.r, i + x.i);
}
Cp operator - (Cp x) {
return Cp(r - x.r, i - x.i);
}
Cp operator * (Cp x) {
return Cp(r * x.r - i * x.i, r * x.i + i * x.r);
}
}; char str1[N], str2[N];
int len1, len2, n, m, l, cnt;
int t[N], ans[N], r[N];
Cp a[N], b[N], A[N], B[N], C[N], tp; void DFT(Cp *s, int f) {
for(int i = ; i < n; ++ i)
if(i < r[i]) swap(s[i], s[r[i]]);
for(int i = ; i < n; i <<= ) {
Cp wn(cos(Pi / i), f * sin(Pi / i));
for(int j = ; j < n; j += (i << )) {
Cp w(, );
for(int k = ; k < i; ++ k) {
Cp x = s[j + k], y = w * s[j + k + i];
s[j + k] = x + y;
s[j + k + i] = x - y;
w = w * wn;
}
}
}
if(f == -)
for(int i = ; i < n; ++ i)
s[i].r /= n;
} #define stone int main() {
#ifndef stone freopen("bitch.in", "r", stdin);
freopen("bitch.out", "w", stdout); #endif scanf("%d%d", &len1, &len2);
scanf("%s%s", str1, str2);
reverse(str1, str1 + len1);
for(int i = ; i < len1; ++ i) {
if(str1[i] == '*') a[i].r = ;
else a[i].r = (str1[i] - 'a' + );
}
for(int i = ; i < len2; ++ i) {
if(str2[i] == '*') b[i].r = ;
else b[i].r = (str2[i] - 'a' + );
}
m = len1 + len2;
for(n = ; n <= m; n <<= ) ++ l;
for(int i = ; i < n; ++ i) r[i] = (r[i >> ] >> ) | ((i & ) << (l - )); for(int i = ; i < n; ++ i) {
A[i].r = a[i].r * a[i].r * a[i].r;
B[i].r = b[i].r;
}
DFT(A, ); DFT(B, );
for(int i = ; i < n; ++ i) { C[i] = C[i] + A[i] * B[i]; }
memset(A, , sizeof A); memset(B, , sizeof B);
for(int i = ; i < n; ++ i) {
A[i].r = a[i].r * a[i].r;
B[i].r = b[i].r * b[i].r;
}
DFT(A, ); DFT(B, ); tp = (Cp) {, };
for(int i = ; i < n; ++ i) { C[i] = C[i] - A[i] * B[i] * tp; }
memset(A, , sizeof A); memset(B, , sizeof B);
for(int i = ; i < n; ++ i) {
A[i].r = a[i].r;
B[i].r = b[i].r * b[i].r * b[i].r;
}
DFT(A, ); DFT(B, );
for(int i = ; i < n; ++ i) { C[i] = C[i] + A[i] * B[i]; }
DFT(C, -);
for(int i = len1 - ; i < len2; ++ i)
if(C[i].r < 0.5) {
ans[++ cnt] = i - len1 + ;
}
printf("%d\n", cnt);
for(int i = ; i <= cnt; ++ i) {
printf("%d ", ans[i]);
} #ifndef stone fclose(stdin); fclose(stdout); #endif return ;
}
4259
题目3 BZOJ 万径人踪灭
算法讨论:
用FFT算出所有回文串(相邻的和不相邻的),然后用Manacher计算出所有相邻的回文串,然后做差统计答案即可。
用FFT算出所有回文串的时候,是有len + len - 1个位置要计算的,分别是在字符的位置上和在两个字符之间的位置。
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath> using namespace std;
const int N = + ;
typedef long long ll;
const int mod = 1e9 + ;
#define Pi acos(-1) struct Cp {
double r, i;
Cp(double _r = , double _i = ) :
r(_r), i(_i){}
Cp operator + (Cp x) {
return Cp(r + x.r, i + x.i);
}
Cp operator - (Cp x) {
return Cp(r - x.r, i - x.i);
}
Cp operator * (Cp x) {
return Cp(r * x.r - i * x.i, r * x.i + i * x.r);
}
}; char ss[N], Ma[N << ];
int n, m, l, r[N], lens;
Cp a[N], b[N];
ll Mp[N << ], t1[N], t2[N], p[N]; void DFT(Cp *s, int f) {
for(int i = ; i < n; ++ i)
if(i < r[i]) swap(s[i], s[r[i]]);
for(int i = ; i < n; i <<= ) {
Cp wn(cos(Pi / i), f * sin(Pi / i));
for(int j = ; j < n; j += (i << )) {
Cp w(, );
for(int k = ; k < i; ++ k) {
Cp x = s[j + k], y = w * s[j + k + i];
s[j + k] = x + y;
s[j + k + i] = x - y;
w = w * wn;
}
}
}
if(f == -)
for(int i = ; i < n; ++ i)
s[i].r /= n;
} ll Manacher(char *s, int len) {
int l = ; ll res = ;
Ma[l ++] = '$';
Ma[l ++] = '#';
for(int i = ; i < len; ++ i) {
Ma[l ++] = s[i];
Ma[l ++] = '#';
}
Ma[l] = '!';
int Mx = , id = ;
for(int i = ; i < l; ++ i) {
if(Mx > i) {
Mp[i] = min(Mp[ * id - i], (ll)Mx - i);
}
else {
Mp[i] = ;
}
while(Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i] ++;
if(i + Mp[i] > Mx) {
Mx = i + Mp[i];
id = i;
}
res += (Mp[i] >> ); res %= mod;
}
return res;
} int main() {
ll ans = , tmp;
scanf("%s", ss);
n = strlen(ss); lens = strlen(ss);
for(int i = ; i < n; ++ i) {
if(ss[i] == 'a')
a[i].r = , b[i].r = ;
else a[i].r = , b[i].r = ;
}
m = (n << ) - ;
for(n = ; n <= m; n <<= ) l ++;
for(int i = ; i < n; ++ i) r[i] = (r[i >> ] >> ) |((i & ) << (l - ));
DFT(a, ); DFT(b, );
for(int i = ; i < n; ++ i) {
a[i] = a[i] * a[i];
b[i] = b[i] * b[i];
}
DFT(a, -); DFT(b, -);
for(int i = ; i <= n; ++ i) {
t1[i] = (ll) (a[i].r + 0.5);
t2[i] = (ll) (b[i].r + 0.5);
}
for(int i = ; i < n; ++ i) {
t1[i] += t2[i];
}
tmp = Manacher(ss, strlen(ss));
p[] = ;
for(int i = ; i <= lens; ++ i)
p[i] = p[i - ] * % mod;
lens = lens + lens - ;
for(int i = ; i < lens; ++ i) {
if(i & ) {
ans = (ans + p[t1[i] >> ] - ) % mod;
}
else {
ans = (ans + (p[(t1[i] - ) >> ] << ) - ) % mod;
}
}
ans = (ans - tmp) % mod;
while(ans < ) {
ans += mod;
ans %= mod;
}
printf("%lld\n", ans);
return ;
}
万径人踪灭
题目4 BZOJ3028
首先很高兴的表示这里的汉堡是承德的。然后表示如果会生成函数的话这就是个输入输出题。
系数是种类,指数是数量性质。
如下图:
然后就没有然后了。知道答案就考虑输入和输出了。表示0ms过没有压力。这题如果你要是写个搜索。。。。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <algorithm>
#include <cctype> using namespace std;
const int N = + ;
const int mod = ;
typedef long long ll; ll n; inline ll read() {
ll x = ;
char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)) {
x = x * + c - '';
x %= mod;
c = getchar();
}
return x;
} int main() {
n = read();
n = n * (n + ) * (n + );
n /= ;
n %= mod;
printf("%lld\n", n);
return ;
}
3028
FFT与多项式、生成函数题目泛做的更多相关文章
- 基尔霍夫矩阵题目泛做(AD第二轮)
题目1: SPOJ 2832 题目大意: 求一个矩阵行列式模一个数P后的值.p不一定是质数. 算法讨论: 因为有除法而且p不一定是质数,不一定有逆元,所以我们用辗转相除法. #include < ...
- 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做
题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...
- 二维计算几何基础题目泛做(SYX第一轮)
题目1: POJ 2318 TOYS 题目大意: 给一个有n个挡板的盒子,从左到右空格编号为0...n.有好多玩具,问每个玩具在哪个空格里面. 算法讨论: 直接叉积判断就可以.注意在盒子的边界上面也算 ...
- 生成树题目泛做(AD第二轮)
题目1: NOI2014 魔法森林 LCT维护MST.解题报告见LOFTER #include <cstdio> #include <iostream> #include &l ...
- K-D Tree题目泛做(CXJ第二轮)
题目1: BZOJ 2716 题目大意:给出N个二维平面上的点,M个操作,分为插入一个新点和询问到一个点最近点的Manhatan距离是多少. 算法讨论: K-D Tree 裸题,有插入操作. #inc ...
- 插头DP题目泛做(为了对应WYD的课件)
题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. #inc ...
- 数学期望和概率DP题目泛做(为了对应AD的课件)
题1: Uva 1636 Headshot 题目大意: 给出一个000111序列,注意实际上是环状的.问是0出现的概率大,还是当前是0,下一个还是0的概率大. 问题比较简单,注意比较大小: A/C & ...
- Link-Cut-Tree题目泛做(为了对应自己的课件)
题目1:BZOJ 2049 洞穴勘测 #include <bits/stdc++.h> #define L(x) c[x][0] #define R(x) c[x][1] using na ...
- 莫比乌斯反演题目泛做(为了对应smz的课件)
题1:BZOJ2190 SDOI 2010 仪仗队 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2190 算法讨论: 我们先来考虑一个点被 ...
随机推荐
- 你好,C++(20).4.2.2 表达并列条件选择的switch语句:如果……如果……如果……
4.2.2 表达并列条件选择的switch语句:如果……如果……如果…… 在现实世界中,还有这样一类特殊的条件选择: 如果明天是晴天,我就穿T恤: 如果明天是阴天,我就穿衬衣: 如果明天是雨天,我就 ...
- win32 console application 如何修改图标?
win32 console application ,不要看这名字高端大气上档次,让你摸不着头脑,其实他就是我们最先学习c语言那种黑色窗口的东西......话说他怎么修改图标呢?第一种方法是:右键-〉 ...
- 转载:JSONObject简介
转载网址:http://www.cnblogs.com/java-pan/archive/2012/04/07/JSONObject.html JSONObject简介 本节摘要:之前对JSON做 ...
- git基础使用小记
一.安装步骤省略二.运行“Git Bash“在打开的窗口中输入:ssh-keygen -t rsa -C "my@gmail.com" 会提示SSH Public Keys存放的位 ...
- 使用GCD的dispatch_once创建单例
使用GCD的dispatch_once创建单例 介绍了创建单例的方式,不过后来发现其实在ios 4.0后有更加简单的方式. 就是使用GCD的功能 代码如下: + (instantClass *)sha ...
- substr vs substring
javascript(js)中的 substring和substr方法 Posted on 2009-02-26 14:14 chinaifne 阅读(33698) 评论(0) 编辑 收藏 1.sub ...
- Jquery让图片根据浏览器窗口大小自动缩放
(function($){ $.fn.resizeimage = function(){ var imgLoad = function (url, callback) { var img = new ...
- python部落刷题宝学到的内置函数
最近加入了python部落,感觉里面的刷题宝很有意思,玩了一下,知道了许多以前并不清楚的内置函数,然后感觉到快要记不住了,所以开始陈列一下 1.divmod(a,b):取a除以b的商和余数,功效等价于 ...
- 深入理解linux网络技术内幕读书笔记(一)--简介
Table of Contents 1 基本术语 1.1 本书常用的缩写 2 引用计数 2.1 引用计数函数 3 垃圾回收 3.1 异步 3.2 同步 4 函数指针 4.1 缺点 5 goto语句 5 ...
- iOS - Usage of NSData
Reference link : https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/BinaryData/T ...