总结
高效进阶
金牌导航
字符串
manacher
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
string a, s;
int r[N];
int intt() //中间加入“#”以便判断偶数回文串
{
s[0]='$';
s[1]='#';
int l=a.size();
int k=1;
for(int i=0;i<l;i++)
{
s[++k]=a[i];
s[++k]='#';
}
s[++k]=' ';
return k;
}
void manacher()
{
int n=intt();
int p=1,mx=1;
for(int i=1;i<=n;i++)
{
if(i<mx) r[i]=min(mx-i,r[p*2-i]);
else r[i]=1;
while(s[i+r[i]]==s[i-r[i]])
r[i]++;
if(i+r[i]>mx)
p=i,mx=i+r[i];
}
}
int main()
{
cin>>a;
manacher();
return 0;
}
图论
二分图匹配.匈牙利算法
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int A, B; // A,B组点数
struct node
{
int siz;
int num[10];
} a[N];
int v[N], p[N]; // 标记,匹配
int cnt;
bool find(int x)
{
for (int i = 1; i <= a[x].siz; i++)
{
if (v[a[x].num[i]])
continue;
v[a[x].num[i]] = 1;
if (!p[a[x].num[i]] || find(p[a[x].num[i]]) // 如果暂无匹配,或者原来匹配的左侧元素可以找到新的匹配
{
p[a[x].num[i]] = x; // 当前左侧元素成为当前右侧元素的新匹配
return 1;
}
}
return 0;
}
void search()
{
for (int i = 1; i <= A; i++)
{
memset(v, 0, sizeof(v));
if (find(i))
cnt++;
}
cout << cnt;
}
int main()
{
cin >> A >> B;
int T;
cin >> T;
while (T--)
{
int x, y;
cin >> x >> y;
a[x].num[++a[x].siz] = y;
}
search();
return 0;
}
/*
4 4
6
1 2
1 4
2 2
3 1
3 3
4 4
3
*/
树上问题
树链剖分
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, root, mod;
// 树的边
vector<int> g[N];
// 节点权值
int w[N];
int head[N], to[N], nxt[N], w[N];
int tot;
void add(int a, int b, int c)
{
nxt[++tot] = head[a], head[a] = tot, to[tot] = b, w[tot] = c;
}
// 树链剖分相关数组
// 每个节点的父节点
int fa[N];
// 每个节点的深度
int dep[N];
// 每个节点的子树大小
int siz[N];
// 每个节点的重儿子
int son[N];
// 节点在线性结构中的编号
int seg[N];
// 每个节点的链头
int top[N];
// 在线性结构中的位置所对应的树中结点编号
int rev[N];
// 点权
int num[N];
// 线段树相关数组
int tr[N << 2];
// 第一次dfs计算fa[],dep[],siz[],son[];
void dfs1(int u, int f, int depth)
{
fa[u] = f;
dep[u] = depth;
siz[u] = 1;
for (int i = head[u]; i; i = nxt[u])
{
int v = to[i];
if (v == f)
continue;
dfs1(v, u, depth + 1);
siz[u] += siz[v];
if (siz[v] > siz[son[u]])
son[u] = v;
}
}
// 第二次dfs确定重链和轻链,给节点编号
void dfs2(int u)
{
if(son[u])
{
seg[son[u]]=++seg[0];
rev[seg[0]]=son[u];
top[son[u]]=top[u];
dfs2(son[u]);
}
for(int i=head[i];i;i=nxt[i])
{
if(!top[u])
{
int v=to[i];
seg[v]=++seg[0];
rev[seg[0]]=son[u];
top[v]=v;
dfs2(v);
}
}
}
// 线段树的build操作
void build(int u, int l, int r)
{
if (l == r)
{
tr[u] = num[rev[l]];
return;
}
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
tr[u] = tr[u << 1] + tr[u << 1 | 1];
}
// 线段树的query操作
int query(int u, int l, int r, int L, int R)
{
if (L <= l && r <= R)
return tr[u];
int mid = l + r >> 1;
int res = 0;
if (L <= mid)
res += query(u << 1, l, mid, L, R);
if (R > mid)
res += query(u << 1 | 1, mid + 1, r, L, R);
return res;
}
// 树链剖分的query操作,求u到v路径上的节点权值之和
int tree_query(int u, int v)
{
int res = 0;
while (top[u] != top[v])
{
if (dep[top[u]] < dep[top[v]])
swap(u, v);
res += query(1, 1, n, seg[top[u]], seg[u]);
u = fa[top[u]];
}
if (dep[u] > dep[v])
swap(u, v);
res += query(1, 1, n, seg[u], seg[v]);
return res;
}
int main()
{
}
本文来自博客园,作者:流氓兔LMT,转载请注明原文链接:https://www.cnblogs.com/-include-lmt/p/18732198

浙公网安备 33010602011771号