So easy
There are n points in an array with index from 11 to n, and there are two operations to those points.
1: q= =1 x marking the point xx is not available
2: q= =2 x query for the index of the first available point after that point (including xx itself) .
Input
q is the number of queries, z is the type of operations, and x is the index of operations. 1≤x<n<109,1≤x<n<109 q<106 and z is 1 or 2.
Output
Output the answer for each query.
样例输入
5 3
1 2
2 2
2 1
样例输出
3
1
题目思路:本想着用数组模拟链表,使每个数字位置的查询直接、或间接等于该数字为下标数组的值,奈何数据量太大,只得用map。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
int a[20000001];
int main()
{
map<int,int>m;
int n,q;
scanf("%d%d",&n,&q);
int z,x;
for(int i=1; i<=q; i++)
{
scanf("%d%d",&z,&x);
if(z==1)
{
int xx=x+1,cnt=1;
a[1]=xx;
while(m.find(xx)!=m.end()&&xx<=n) {
xx=m[xx];//寻找合适的位置
a[++cnt]=xx;
}
m[x]=xx;
for(int i=1;i<cnt;i++) m[a[i]]=xx;//减少重复计算,以减少复杂度
}
if(z==2)
{
if(m.find(x)==m.end()) printf("%d\n",x);
else
{
int xx=m[x];
while(m.find(xx)!=m.end()&&xx<=n) xx=m[xx];//循环的到对应值
m[x]=xx;
if(xx==n+1) printf("-1\n");
else printf("%d\n",xx);
}
}
}
}
标准题解:思路基本一致,题解做到优化为递归,进一步减少复杂度
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 100;
unordered_map<int, int> fa;
int findfa(int x) {
if (!fa.count(x)) return x;
return fa[x] = findfa(fa[x]);
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n, q;
scanf("%d %d", &n, &q);
int op, x;
while (q--) {
scanf("%d %d", &op, &x);
if (op == 1) {
fa[x] = findfa(x + 1);
} else {
int ans = findfa(x);
if (ans > n) ans = -1;
printf("%d\n", ans);
}
}
return 0;
}