by Jomoo

1 杂类算法

1.1 快读模板

template <typename Int>
inline Int read()
{
Int flag = 1;
char c = getchar();
while ((!isdigit(c)) && c != '-') c = getchar();
if (c == '-') flag = -1, c = getchar();
Int init = c & 15;
while (isdigit(c = getchar())) init = (init << 3) + (init << 1) + (c & 15);
return init * flag;
} template <typename Int>
inline Int read(char &c)
{
Int flag = 1;
c = getchar();
while ((!isdigit(c)) && c != '-') c = getchar();
if (c == '-') flag = -1, c = getchar();
Int init = c & 15;
while (isdigit(c = getchar())) init = (init << 3) + (init << 1) + (c & 15);
return init * flag;
} template <typename Int>
inline void write(Int x)
{
if (x < 0) putchar('-'), x = ~x + 1;
if (x > 9) write(x / 10);
putchar((x % 10) | 48);
} template <typename Int>
inline void write(Int x, char nextch)
{
write(x);
putchar(nextch);
} int main()
{
return 0;
}

1.2 O(1) int64 乘法

LL mul(LL a, LL b, LL P){
LL L = a * (b >> 25LL) % P * (1LL << 25) % P;
LL R = a * (b & ((1LL << 25) - 1)) % P;
return (L + R) % P;
}

2 图论算法

2.1 树类 - Trie

#define TrieNodeMax 100007
// should @using namespace std
template <int charSetSize = 26, char base = 'a'>
struct Trie {
bool isEndStr[TrieNodeMax];
int son[TrieNodeMax][charSetSize], top = 1;
bool insert(string s)
{
int u = 1;
for (int i = 0; i < s.length(); i++) {
if (!son[u][s[i] - base]) {
son[u][s[i] - base] = ++top;
} else if (isEndStr[son[u][s[i] - base]] || i == s.length() - 1) return 0;
u = son[u][s[i] - base];
if (i == s.length() - 1) isEndStr[u] = 1;
}
return 1;
}
};

2.2 树类 - 并查集(NB version)

复杂度 \(O(n\alpha{(n)})\),不用辅助数组

struct UFS {
int fa[400007];
int familyCnt; UFS() : familyCnt(0)
{
memset(fa, -1, sizeof(fa));
} int find(int u)
{
return fa[u] < 0 ? u : fa[u] = find(fa[u]);
} void connect(int x, int y)
{
int xx = find(x), yy = find(y);
if (xx == yy) return;
if (fa[xx] > fa[yy]) swap(xx, yy);
fa[xx] += fa[yy];
fa[yy] = xx;
familyCnt--;
} bool isFamily(int u, int v)
{
return find(u) == find(v);
}
} fam;

2.3 树类 - LCA

void dfs_LCA(int now, int depth)
{
use[now] = true;
deep[now] = depth;
for (rg int k = 1; k <= SizeLogN; k++){
f[now][k] = f[f[now][k - 1]][k - 1];
}
for (rg EDGE *nxt = v[now]; nxt; nxt = nxt->next_edge) {
if(!use[nxt->e]) {
f[nxt->e][0] = now;
dfs_LCA(nxt->e, depth + 1);
}
}
// use[now] = false;
} inline int jump(int u, int depth) {
for (rg int k = 0; k <= SizeLogN; k++) {
if ((depth & (1 << k))) u = f[u][k];
}
return u;
} inline int LCA(int u, int v){
if (deep[u] < deep[v]) swap(u, v);
u = jump(u, deep[u] - deep[v]);
for (rg int k = SizeLogN; k >= 0; k--) {
if (f[u][k] != f[v][k]) u = f[u][k], v = f[v][k];
}
return u == v ? u : f[u][0];
} f[s][0] = 0;
dfs_LCA(s, 0);
LCA(u, v);

2.4 树类 - 超级树状数组

\[sum[i]=\sum_{j=1}^ia[j]+\sum_{j=1}^idelta[j]*(i-j+1)
\]

\[sum[i]=\sum_{j=1}^ia[j]+(i+1)*\sum_{j=1}^idelta[j]-\sum_{j=1}^idelta[j]*j
\]

\(basicSum\) 数组维护 \(a\) 数组的前缀和

\(delta1\) 与 \(delta2\) 两个树状数组,\(delta1\) 维护 \(delta\) 数组的和,\(delta2\) 维护\(delta[i]*i\) 的和

template <typename Int>
class super_BIT {
private:
Int n;
Int *basicSum, *delta1, *delta2; Int lowbit(Int x)
{
return x & (-x);
} void arr_add(Int *arr, Int pos, Int x)
{
while (pos <= n) {
arr[pos] += x;
pos += lowbit(pos);
}
} Int arr_getsum(Int *arr, Int pos)
{
Int sum = 0;
while (pos) {
sum += arr[pos];
pos -= lowbit(pos);
}
return sum;
} void free_space()
{
delete[] basicSum;
delete[] delta1;
delete[] delta2;
}
public:
super_BIT()
{
basicSum = NULL;
delta1 = NULL;
delta2 = NULL;
}
~super_BIT()
{
free_space();
} void init(Int size, Int *arr = NULL)
{
free_space();
n = size;
basicSum = new Int[size + 1];
delta1 = new Int[size + 1];
delta2 = new Int[size + 1];
memset(basicSum, 0, (size + 1) * sizeof(Int));
memset(delta1, 0, (size + 1) * sizeof(Int));
memset(delta2, 0, (size + 1) * sizeof(Int));
if (arr != NULL) {
for (Int i = 1; i <= n; i++) {
basicSum[i] = basicSum[i - 1] + arr[i];
}
}
} void modify(Int l, Int r, Int x)
{
arr_add(delta1, l, x);
arr_add(delta1, r + 1, -x);
arr_add(delta2, l, x * l);
arr_add(delta2, r + 1, -x * (r + 1));
} Int getsum(Int r)
{
return basicSum[r] + arr_getsum(delta1, r) * (r + 1) - arr_getsum(delta2, r);
} Int query(Int l, Int r)
{
return getsum(r) - getsum(l - 1);
} void sample(string problem)
{
if (problem == "LOJ - #132") {
Int N, Q;
Int *a = new Int[1000001];
N = read<Int>();
Q = read<Int>();
for (Int i = 1; i <= N; i++) {
a[i] = read<Int>();
}
init(N, a);
Int type, l, r, x;
while (Q--) {
type = read<Int>();
if (type == 1) {
l = read<Int>();
r = read<Int>();
x = read<Int>();
modify(l, r, x);
} else {
l = read<Int>();
r = read<Int>();
write(query(l, r), 10);
}
debug();
}
} else {
// do
}
}
};

2.5 树类 - 平衡树(STL)

#include <bits/stdc++.h>
using namespace std; int main() {
vector<int> nums;
int q;
scanf("%d", &q);
while (q--) {
int t, x;
scanf("%d %d", &t, &x);
if (t == 1) {
nums.insert(upper_bound(nums.begin(), nums.end(), x), x);
} else if (t == 2) {
nums.erase(lower_bound(nums.begin(), nums.end(), x));
} else if (t == 3) {
printf("%d\n", lower_bound(nums.begin(), nums.end(), x) - nums.begin() + 1);
} else if (t == 4) {
printf("%d\n", nums[x - 1]);
} else if (t == 5) {
printf("%d\n", *--lower_bound(nums.begin(), nums.end(), x));
} else {
printf("%d\n", *upper_bound(nums.begin(), nums.end(), x));
}
}
return 0;
}

2.6 树类 AC-Trie

2.6.1 模板 1

给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。

n行模式串

1行文本串

struct ACtrie {
ACtrie *fail, *son[charSize];
int count;
bool found;
int fa_sonId; // 在爸爸那里自己的ID,即本节点代表的字母
ACtrie() : fail(NULL), count(0), found(0), fa_sonId('~' - baseChar)
{
memset(son, 0, sizeof(son));
}
}; ACtrie *root = new ACtrie; void insert(string s)
{
ACtrie *p = root;
for (string::iterator it = s.begin(); it != s.end(); it++) {
if (!p->son[*it - baseChar]) {
p->son[*it - baseChar] = new ACtrie;
p->son[*it - baseChar]->fa_sonId = *it - baseChar;
}
p = p->son[*it - baseChar];
}
p->count++;
} void make_fail()
{
queue<ACtrie*> q;
for (int i = 0; i < charSize; i++) {
if (root->son[i]) {
// printf("CNT 63 - %c.\n", i + baseChar);
q.push(root->son[i]);
root->son[i]->fail = root;
}
}
while (!q.empty()) {
ACtrie *p = q.front();
q.pop();
for (int i = 0; i < charSize; i++) {
if (!p->son[i]) continue;
ACtrie *f = p->fail;
while (true) {
if (f->son[i]) {
p->son[i]->fail = f->son[i];
break;
}
if (f == root) {
p->son[i]->fail = root;
break;
}
f = f->fail;
}
q.push(p->son[i]);
}
}
} void build_ACtrie(vector<string> sArr)
{
for (vector<string>::iterator it = sArr.begin(); it != sArr.end(); it++) {
insert(*it);
}
make_fail();
} int match_task1(string txt) // 有多少个模式串在文本串里出现过(多次出现答案只算1,重复的模式串答案算多个)
{
ACtrie *u = root, *v;
int ans(0);
for (string::iterator it = txt.begin(); it != txt.end(); it++) {
if (u->son[*it - baseChar]) u = u->son[*it - baseChar];
else {
while (!u->son[*it - baseChar] && u != root) {
u = u->fail;
}
if (u->son[*it - baseChar]) {
u = u->son[*it - baseChar];
}
} v = u;
while (v->count && !v->found) {
ans += v->count;
v->found = true;
v = v->fail;
}
}
return ans;
} int main()
{
int n = read<int>();
string s, txt;
vector<string> v;
for (int i = 1; i <= n; i++) {
cin >> s;
v.push_back(s);
}
build_ACtrie(v);
cin >> txt;
write(match_task1(txt), 10);
return 0;
}

2.6.2 模板 2

有 N 个由小写字母组成的模式串以及一个文本 T 。每个模式串可能会在文本串中出现多次。你需要找出(b)哪些(/b)模式串在文本串 T 中出现的次数最多。

n行模式串

1行文本串

int TJ[150 + 7];
const int charSize = 26;
const char baseChar = 'a'; struct ACtrie {
ACtrie *fail, *son[charSize];
int count;
string originalString;
bool found;
int inputId;
int fa_sonId; // 在爸爸那里自己的ID,即本节点代表的字母
ACtrie() : fail(NULL), count(0), found(0), fa_sonId('~' - baseChar)
{
memset(son, 0, sizeof(son));
}
}; ACtrie *root = new ACtrie; void insert(string s, int inputId)
{
ACtrie *p = root;
for (string::iterator it = s.begin(); it != s.end(); it++) {
if (!p->son[*it - baseChar]) {
p->son[*it - baseChar] = new ACtrie;
p->son[*it - baseChar]->fa_sonId = *it - baseChar;
}
p = p->son[*it - baseChar];
}
p->count++;
p->originalString = s;
p->inputId = inputId;
} void make_fail()
{
queue<ACtrie*> q;
for (int i = 0; i < charSize; i++) {
if (root->son[i]) {
q.push(root->son[i]);
root->son[i]->fail = root;
}
}
while (!q.empty()) {
ACtrie *p = q.front();
q.pop();
for (int i = 0; i < charSize; i++) {
if (!p->son[i]) continue;
ACtrie *f = p->fail;
while (true) {
if (f->son[i]) {
p->son[i]->fail = f->son[i];
// printf("char %c:find my pFail!\n", i + baseChar);
break;
}
if (f == root) {
p->son[i]->fail = root;
break;
}
f = f->fail;
}
q.push(p->son[i]);
}
}
} void build_ACtrie(vector<string> sArr)
{
int count = 0;
for (vector<string>::iterator it = sArr.begin(); it != sArr.end(); it++) {
insert(*it, count++);
}
make_fail();
} void match(string txt)
{
ACtrie *u = root, *v;
for (string::iterator it = txt.begin(); it != txt.end(); it++) {
if (u->son[*it - baseChar]) u = u->son[*it - baseChar];
else {
while (!u->son[*it - baseChar] && u != root) {
u = u->fail;
}
if (u->son[*it - baseChar]) {
u = u->son[*it - baseChar];
}
} v = u;
while (v != root) {
if (v->count) TJ[v->inputId]++;
v = v->fail;
}
}
} void clean(ACtrie *rt = root)
{
rt->originalString = "";
rt->count = 0;
rt->inputId = 0;
rt->fail = NULL;
for (int i = 0; i < charSize; i++) {
if (rt->son[i]) {
clean(rt->son[i]);
// delete rt->son[i];
}
}
} struct forSort {
string s;
int id;
int val;
bool operator < (const forSort &other) const {
return val ^ other.val ? val > other.val : id < other.id;;
}
} a[150 + 7]; int main()
{
int n = read<int>();
if (!n) return 0;
sPosTAG:
memset(Jalg::TJ, 0, sizeof(Jalg::TJ));
Jalg::clean();
string s, txt;
vector<string> v;
for (int i = 1; i <= n; i++) {
cin >> s;
v.push_back(s);
}
Jalg::build_ACtrie(v);
cin >> txt;
Jalg::match(txt);
for (int i = 0; i < n; i++) {
a[i] = (forSort){v[i], i, Jalg::TJ[i]};
}
sort(a, a + n);
int ans = a[0].val;
write(ans, 10);
int i = 0;
while (i < n && a[i].val == ans) {
printf("%s\n", a[i++].s.c_str());
}
n = read<int>();
if (n) goto sPosTAG;
return 0;
}

2.7 图类 - 迪杰斯特拉

struct Graph {
struct Node {
int u, val;
bool operator < (const Node &other) const
{
return val > other.val;
}
};
struct Edge {
int v, w;
} e[200007];
int head[100007], next[200007], edgeCnt; Graph() : edgeCnt(0)
{
memset(head, -1, sizeof(head));
} void addEdge(int u, int v, int w)
{
e[++edgeCnt] = (Edge){v, w};
next[edgeCnt] = head[u];
head[u] = edgeCnt;
} void dij(int n, int s, int *dis)
{
memset(dis, 0x3f, sizeof(int) * (n + 1));
dis[s] = 0;
priority_queue<Node> q;
q.push((Node){s, 0});
while (!q.empty()) {
while (q.top().val != dis[q.top().u] && !q.empty()) q.pop();
if (q.empty()) break;
int fr = q.top().u;
q.pop();
#define to e[i].v
#define va e[i].w
for (int i = head[fr]; ~i; i = next[i]) {
if (dis[to] - va > dis[fr]) {
dis[to] = dis[fr] + va;
q.push((Node){to, dis[to]});
}
}
#undef to
#undef va
}
}
} G; int main()
{
int n, m, s;
int u, v, w;
n = read<int>();
m = read<int>();
s = read<int>();
while (m--) {
u = read<int>();
v = read<int>();
w = read<int>();
G.addEdge(u, v, w);
}
int *dis = new int[n + 1];
G.dij(n, s, dis);
for (int i = 1; i <= n; i++) {
write
(dis[i], 32);
}
return 0;
}

2.8 图类 - SPFA(带卡界)判负环

struct Edge {
int v, w;
int nxt;
Edge() {}
Edge(int _v, int _w, int _nxt) : v(_v), w(_w), nxt(_nxt) {}
} edges[6007];
// 链式前向星存图
int top = 1;
int n, m; int head[2007] = {0};
int dis[2007] = {0};
bool inqueue[2007] = {0}; inline void add_edge(int u, int v, int w) // 单次加边操作
{
edges[top] = Edge(v, w, head[u]);
head[u] = top++;
} inline void add(int u, int v, int w) // 加边操作
{
add_edge(u, v, w);
if (w >= 0) add_edge(v, u, w);
} const double K = 20.076030; // 即题解中所说的 "T"
bool SPFA_bfs()
{
queue <int> q;
q.push(1);
inqueue[1] = 1;
int times = 0;
while (!q.empty()) {
times++;
if (times > K * (n + m)) return 1;
// 以上两行:卡界
int n = q.front(); q.pop();
inqueue[n] = 0;
for (int i = head[n]; i != -1; i = edges[i].nxt) {
Edge &e = edges[i];
if (dis[e.v] > dis[n] + e.w) {
dis[e.v] = dis[n] + e.w;
if (!inqueue[e.v]) q.push(e.v);
}
}
}
return 0;
} void van()
{
n = readint();
m = readint();
top = 1;
memset(head, -1, sizeof(head));
memset(dis, 0x3f, sizeof(dis));
memset(inqueue, 0, sizeof(inqueue));
dis[1] = 0;
register int ui, vi, wi;
for (register int i = 1; i <= m; i++) {
ui = readint();
vi = readint();
wi = readint();
add(ui, vi, wi);
}
if (SPFA_bfs()) puts("YE5");
else puts("N0");
} int main()
{
register int T = readint();
while (T--) van();
return 0;
}

2.9 图类 - 网络流

P2045 方格取数加强版

struct Edge {
int u, v, w;
int cost;
int next;
Edge() {}
Edge(int _u, int _v, int _w, int _cost, int _next) : u(_u), v(_v), w(_w), cost(_cost), next(_next) {}
}; int n, k, s, t;
Edge edges[300007];
int head[5007], top = 0;
int could[5007];
int road[5007];
int pre[5007]; template <typename _Tp>
void queue_clear(queue<_Tp> &a)
{
queue<_Tp> empty;
swap(a, empty);
}
queue <int> q; void _add_once(int u, int v, int w, int cost)
{
edges[top] = Edge(u, v, w, cost, head[u]);
head[u] = top++;
} void add(int u, int v, int w, int cost)
{
_add_once(u, v, w, cost);
_add_once(v, u, 0, -cost);
} // 如果你想查看一些 DEBUG ,请去掉下一行开头的注释符号
// #define TEST_OPEN
// 【警告:仅限小数据(如小样例)】 #ifndef TEST_OPEN
#define fprintf(...)
#endif int dis[10007];
bool SPFA()
{
queue_clear(q);
bool vis[10007] = {0};
memset(dis, 0x3f, sizeof(dis));
memset(could, 0x3f, sizeof(could));
dis[s] = 0;
vis[s] = 1;
q.push(s);
while (!q.empty()) {
int now = q.front();
q.pop();
vis[now] = 0;
for (int nNow = head[now]; nNow != -1; nNow = edges[nNow].next) {
Edge &e = edges[nNow];
if (e.w > 0 && dis[e.v] > dis[now] + e.cost) {
dis[e.v] = dis[now] + e.cost;
road[e.v] = nNow;
could[e.v] = min(could[now], e.w);
pre[e.v] = now;
if (!vis[e.v]) {
q.push(e.v);
vis[e.v] = 1;
}
}
}
}
if (dis[t] != 0x3f3f3f3f) return true; // success
else return false; // unsuccess
} void EK_MCMF()
{
// EK_MCMF : 基于 EK 的 MCMF 算法
// (Edmonds Karp's "Min Cost Max Flow" algorithm)
int maxflow = 0, mincost = 0;
#ifdef TEST_OPEN
int count = 0;
#endif
while (SPFA()) {
for (int pNow = t; pNow != s; pNow = pre[pNow]) {
edges[road[pNow]].w -= could[t];
edges[road[pNow] ^ 1].w += could[t];
}
maxflow += could[t];
mincost += dis[t] * could[t];
}
printf("%d", -mincost);
#ifdef TEST_OPEN
printf("\nDUBUG:maxflow = %d.\n", maxflow);
#endif
} enum IN_OUT {
IN = 0,
OUT = 1
}; int getrank(int x, int y, IN_OUT status)
{
return status * n * n + (x - 1) * n + y;
} int main()
{
memset(head, -1, sizeof(head));
scanf("%d%d", &n, &k);
s = 0;
t = getrank(n, n, OUT) + 1;
add(s, getrank(1, 1, IN), k, 0);
add(getrank(n, n, OUT), t, k, 0);
int aij;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &aij);
add(getrank(i, j, IN), getrank(i, j, OUT), 1, -aij);
add(getrank(i, j, IN), getrank(i, j, OUT), k - 1, 0);
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j < n; j++) {
add(getrank(i, j, OUT), getrank(i, j + 1, IN), k, 0);
}
}
for (int i = 1; i < n; i++) {
for (int j = 1; j <= n; j++) {
add(getrank(i, j, OUT), getrank(i + 1, j, IN), k, 0);
}
}
EK_MCMF();
return 0;
}

3 字符串算法

3.1 KMP

int nxt[1000007];
int n, m;
char a[1000007], b[1000007]; void GetNext()
{
int j = 0, k = -1;
nxt[0] = -1;
while (j < m) {
if (k == -1 || b[j] == b[k]) nxt[++j] = ++k;
else k = nxt[k];
}
} void Match()
{
int j = -1, k = -1;
while (j < n) {
// printf("j %d k %d.\n", j, k);
if (k == -1 || a[j] == b[k]) j++, k++;
else k = nxt[k];
if (k == m) write(j - m + 1, 10), k = nxt[k];
}
} int main()
{
scanf("%s%s", a, b);
n = strlen(a);
m = strlen(b);
GetNext();
// for (int i = 0; i < m; i++) nxt[i]++;
Match();
// for (int i = 0; i < m; i++) write(nxt[i] + 1, 32);
for (int i = 1; i <= m; i++) write(nxt[i], 32);
return 0;
}

3.2 manacher

char str[22000007] = {'|', '^'};
int ans[22000007] = {0}; int main()
{
char ch;
int len = 2;
while ((ch = getchar()) != EOF) {
str[len] = ch;
len++;
str[len] = '^';
len++;
} int mi_2(0), right(0);
int maxLen = 0;
for (int i = 1; i < len; i++) {
ans[i] = right > i ? min(ans[mi_2 - i], right - i) : 1; while (str[i + ans[i]] == str[i - ans[i]])
ans[i]++; if (right < i + ans[i]) {
right = i + ans[i];
mi_2 = i << 1;
} if (maxLen < ans[i])
maxLen = ans[i];
}
write(maxLen - 1);
return 0;
}

4 数论算法

4.1 FFT

version = fast,经典,不是我写的

#define Maxn 1350000
using namespace std;
const double Pi=acos(-1);
int n,m;
struct CP
{
CP (double xx=0,double yy=0){x=xx,y=yy;}
double x,y;
CP operator + (CP const &B) const
{return CP(x+B.x,y+B.y);}
CP operator - (CP const &B) const
{return CP(x-B.x,y-B.y);}
CP operator * (CP const &B) const
{return CP(x*B.x-y*B.y,x*B.y+y*B.x);}
}f[Maxn<<1],p[Maxn<<1];
int tr[Maxn<<1];
void fft(CP *f,bool flag)
{
for (int i=0;i<n;i++)
if (i<tr[i])swap(f[i],f[tr[i]]);
//枚举区间长度
for(int p=2;p<=n;p<<=1){
int len=p>>1;//待合并的长度
CP tG(cos(2*Pi/p),sin(2*Pi/p));
if(!flag)tG.y*=-1;//p次单位根
for(int k=0;k<n;k+=p){//枚举起始点
CP buf(1,0);//遍历一个子问题并合并
for(int l=k;l<k+len;l++){
CP tt=buf*f[len+l];
f[len+l]=f[l]-tt;
f[l]=f[l]+tt;
buf=buf*tG;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=0;i<=n;i++)scanf("%lf",&f[i].x);
for (int i=0;i<=m;i++)scanf("%lf",&p[i].x);
for(m+=n,n=1;n<=m;n<<=1);
for(int i=0;i<n;i++)
tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0);
fft(f,1);fft(p,1);//DFT
for(int i=0;i<n;++i)f[i]=f[i]*p[i];
fft(f,0);
for(int i=0;i<=m;++i)printf("%d ",(int)(f[i].x/n+0.49));
return 0;
}

version=slow,基础,我写的

struct complex {
double x, y;
complex(double xx = 0, double yy = 0) : x(xx), y(yy) {} complex operator + (complex b)
{
return complex(x + b.x, y + b.y);
} complex operator - (complex b)
{
return complex(x - b.x, y - b.y);
} complex operator * (complex b)
{
return complex(x * b.x - y * b.y, x *b.y + y * b.x);
}
} b[Maxn], c[Maxn];
// struct_complex and operations
int n, m, r[Maxn]; void fft(complex *f, int op)
{
for (int i = 0; i < n; i++) {
if (i < r[i]) {
complex tmp = f[i];
f[i] = f[r[i]];
f[r[i]] = tmp;
}
}
for (int p = 2; p <= n; p <<= 1) {
// $ O(log_n) $
int len = p / 2;
complex tmp(cos(Pi / len), op * sin(Pi / len));
for (register int k = 0; k < n; k += p) {
// $ O(log_n) $
register complex buf(1, 0);
for (register int l = k; l < k + len; l++) {
// $ O(log_n) $
register complex tt = buf * f[len + l];
f[len + l] = f[l] - tt;
f[l] = f[l] + tt;
buf = buf * tmp;
}
}
}
} int main()
{
n = read<int>();
m = read<int>();
for (register int i = 0; i <= n; i++) {
b[i].x = read<int>();
}
for (register int i = 0; i <= m; i++) {
c[i].x = read<int>();
}
m += n;
n = 1;
while (n <= m) {
n <<= 1;
}
for (int i = 0; i < n; i++) {
r[i] = (r[i >> 1] >> 1) | ((i & 1) ? n >> 1 : 0);
}
fft(b, 1);
fft(c, 1);
// DFT
for (register int i = 0; i < n; i++) b[i] = b[i] * c[i];
fft(b, -1);
// IDFT
for (register int i = 0; i <= m; i++) {
printf("%.0f ", fabs(b[i].x) / n);
}
return 0;
}

Jomoo的模板的更多相关文章

  1. Jade模板引擎让你飞

    写在前面:现在jade改名成pug了 一.安装 npm install jade 二.基本使用 1.简单使用 p hello jade! 渲染后: <p>hello jade!</p ...

  2. ABP入门系列(2)——通过模板创建MAP版本项目

    一.从官网创建模板项目 进入官网下载模板项目 依次按下图选择: 输入验证码开始下载 下载提示: 二.启动项目 使用VS2015打开项目,还原Nuget包: 设置以Web结尾的项目,设置为启动项目: 打 ...

  3. CMS模板应用调研问卷

    截止目前,已经有数十家网站与我们合作,进行了MIP化改造,在搜索结果页也能看到"闪电标"的出现.除了改造方面的问题,MIP项目组被问到最多的就是:我用了wordpress,我用了织 ...

  4. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  5. 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送

    微信支付之微信模板消息推送                    今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...

  6. OpenCV模板匹配算法详解

    1 理论介绍 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否“相似”,当相似度足够高时,就认为找到了我们的目标.OpenCV ...

  7. 前端MVC学习总结(一)——MVC概要与angular概要、模板与数据绑定

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.AngularJS是框架而jQuery则是库. 1.2. ...

  8. ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案

    好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下: 出现乱码的原因: ...

  9. ThinkPHP 模板substr的截取字符串函数

    ThinkPHP 模板substr的截取字符串函数在Common/function.php加上以下代码 /** ** 截取中文字符串 **/ function msubstr($str, $start ...

随机推荐

  1. Python 基础 三 反射

    Python 基础 三 反射 今天我们先介绍一下反射这个概念,啥是反射?反射就是自己检测自己.在我们Python的面向对象中的反射是啥意思呢?就是通过字符串的形式操作对象相关的属性.python中的一 ...

  2. CMDB连接方式

    1.agent agent (放在每台客户端服务器上,定时任务) 脚本演示 # 采集本机的信息 执行命令 import subprocess v1 = subprocess.getoutput('ip ...

  3. ios遇到的坑

    总结体会:很多ios兼容性问题都是由于body设置了height:100% ios中input输入不了 在ios中margin属性不起作用 设置html body的高度为百分比时,margin-bot ...

  4. Nginx Linux和Windows安装教程

    前言 本篇文章主要介绍的是Nginx Linux环境和Windows的安装教程. Nginx 介绍 Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Syso ...

  5. deepin 、 windows10,双系统安装

    deepin . windows10,双系统安装: 首先,最好专门分一个盘用来存放deepin操作系统的安装位置(我这里分给它60个G). 1.在 http://rsync.deepin.com/de ...

  6. zabbix 发送报警邮件

  7. 利用tomcat搭建图片服务器

    今天来教大家如何使用 tomcat 来搭建一个图片的服务器 1.先将tomcat解压一份并改名 2.此时apache-tomcat-8.5.43-windows-x64-file为图片服务器 依次打开 ...

  8. web前端之css基础

    CSS选择器 元素选择器 p{color:red;} ID选择器 #li{ background-color:red; } 类选择器 .c1{ font-size:15px; } 注意: 样式类名不要 ...

  9. ansible roles 介绍和使用

    目录 roles roles 介绍 创建role的步骤 role内个目录中可用的文件 案例 roles roles 介绍 ansible 自1.2版本引入的新特性,用于层次性.结构化地组织playbo ...

  10. yarn和npm的对比以及yarn的使用

    0--前言 为什么要使用yarn,如果你从事前端开发有些年头了,那你肯定对npm又爱又恨,爱就不说了,恨嘛,就是NPM经常奇慢和卡顿,这还能忍,经常各种错误就没法忍了,尤其是他人创建的项目,自己在安装 ...