点击跳转例题
思路:我们发现了特性:
一.如果要确定一个答案,如样例,确定第二个1的时候,我们怎么直接找到3呢?我们是不是可以找到1直接指向的哪个数,这样就降低了时间复杂度为O(1),那么这个过程就有点想并查集路径压缩之后,某个点直接指向根节点。那么总共两类点:指向自己和指向根节点。
那么我们可以使用并查集。
二.因为n的范围为n,所以我们确定每个数只有复杂度为O(1)或者O(logn)所以我们考虑对应的算法。考虑二分-->寻找单调性,二段性。确定每个数的答案,发现要么是本身,要么是比自己大的数。所以有二段性:大于等于自身的都满足。每次就找到(排除确定的数)大于等于自己的数即可。
一,并查集:#include <bits/stdc++.h> #define int long long //(有超时风险) #define PII pair<int,int> #define endl '\n' #define LL __int128 using namespace std; const int N=2e5+10,M=1e3+10,mod=998244353,INF=0x3f3f3f3f; int a[N],b[N],c[N],pre[N]; int p[N],sz[N],d[N]; int find(int x) { if(p[x]!=x) { p[x]=find(p[x]); } return p[x]; } signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n;cin>>n; for(int i=1;i<=n+1;i++) p[i]=i; for(int i=1;i<=n;i++) { int x;cin>>x; int px=find(x); if(x==px) { cout<<x<<' '; } else { cout<<px<<' '; } p[px]=px+1; } return 0; }
二,二分:
#include <bits/stdc++.h> #define int long long //(有超时风险) #define PII pair<int,int> #define endl '\n' #define LL __int128 using namespace std; const int N=2e5+10,M=1e3+10,mod=998244353,INF=0x3f3f3f3f; signed main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n;cin>>n; set<int>st; for(int i=1;i<=1e6+10;i++) st.insert(i); for(int i=1;i<=n;i++) { int x;cin>>x; auto it=st.lower_bound(x); st.erase(it); cout<<*it<<' '; } return 0; }
P8686 [蓝桥杯 2019 省 A] 修改数组--2024蓝桥杯冲刺省一
最新推荐文章于 2024-07-24 20:44:05 发布