总结

高效进阶

金牌导航

字符串

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()
{
	
}
posted @ 2025-02-23 16:03  流氓兔LMT  阅读(15)  评论(0)    收藏  举报