1.修改数组
并查集的应用
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 11e5 + 10;
int p[N];
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main() {
int n; scanf("%d", &n);
for (int i = 1; i < N; i ++) p[i] = i;
for (int i = 1; i <= n; i ++) {
int x; scanf("%d", &x);
x = find(x); p[x] = x + 1;
printf("%d ", x);
}
return 0;
}
2.距离 acwing1171
最近公共祖先
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=200100,M=N*2;
int n,m;
int h[N],e[M],w[M],ne[M],idx;
int dis[N];
int p[N];
int st[N];
int res[N];
vector<PII> query[N];//first 存查询的另外一个点 second存查询的编号
void add(int a,int b,int c)
{
e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
void dfs(int u,int fa)
{
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
dis[j]=dis[u]+w[i];
dfs(j,u);
}
}
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void tarian(int u)
{
st[u]=1;
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(!st[j])
{
tarian(j);
p[j]=u;
}
}
for(auto item:query[u])
{
int y=item.first;
int id=item.second;
if(st[y]==2)
{
int anc=find(y);
res[id]=dis[u]+dis[y]-2*dis[anc];
}
}
st[u]=2;
}
int main()
{
scanf("%d%d",&n,&m);
memset(h,-1,sizeof h);
for(int i=0;i<n-1;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c),add(b,a,c);
}
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(a!=b)
{
query[a].push_back({b,i});
query[b].push_back({a,i});
}
}
for(int i=1;i<=n;i++)
p[i]=i;
dfs(1,-1);
tarian(1);
for(int i=0;i<m;i++)
printf("%d\n",res[i]);
return 0;
}
3.模拟散列表
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 3, null = 0x3f3f3f3f;
int a[N];
int n;
int insert(int x) {
int t = (x % N + N) % N;
while (a[t] != null && a[t] != x) {
t++;
if (t == N) {
t = 0;
}
}
return t; //如果这个位置是空的, 则返回的是他应该存储的位置
}
int main() {
memset(a, 0x3f, sizeof a);
scanf("%d", &n);
while (n--) {
char d[2];
int x;
scanf("%s%d", d, &x);
if (d[0] == 'I')
a[insert(x)] = x;
else {
if (a[insert(x)] != null)
puts("Yes");
else
puts("No");
}
}
return 0;
}
4.包子凑数
dp+gcd
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e4 + 10, M = 110;
int a[M];
bool f[N];
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
int main() {
int n; scanf("%d", &n);
int d = 0;
for (int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
d = gcd(d, a[i]);
}
if (d != 1) printf("INF\n");
else {
f[0] = true;
for (int i = 1; i <= n; i ++)
for (int j = a[i]; j < N; j ++)
f[j] |= f[j -a[i]];
int res = 0;
for (int i = 0; i < N; i ++)
if (!f[i]) res ++;
printf("%d\n", res);
}
return 0;
}