有题了再放链接。
A
考虑从大到小考虑每一个取值的数,如果能换就换,如果换了没用就不换。
实现上使用 vector 存下标,复杂度 \(O(n)\)。
#include<bits/stdc++.h>
using namespace std;
int t,n,m,a[1000005],flag,tim;
vector<int> v[1000005],ans,out;
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>t;while(t--){cin>>n;for(int i=1;i<=n;i++){cin>>a[i];v[a[i]].push_back(i);}ans.push_back(0);ans.push_back(0);m=ans.size();for(int i=n;i>=1;i--){if(!v[i].size()) continue;flag=false;for(int j=0;j<v[i].size();j++){if(v[i][j]<ans[m-1] && v[i][j]>ans[m-2]) flag=true;}if(flag && !tim){tim=1;ans[m-1]=ans[m-2];}for(int j=0;j<v[i].size();j++){if(v[i][j]>ans[m-1]) ans.push_back(v[i][j]),out.push_back(i);}m=ans.size();}cout<<out[0];for(int i=1;i<out.size();i++){cout<<' '<<out[i];}tim=m=0;out.clear();ans.clear();for(int i=1;i<=n;i++){v[i].clear();}if(t) cout<<'\n';}return 0;
}
B
考虑建出树,然后倒序考虑每一个叶子。每次询问时,暴力跳父亲并标记节点,这个叶子的答案就是最后一个没有被标记的祖先的深度。
实现上 dfs 即可,复杂度 \(O(n)\)。
#include<bits/stdc++.h>
using namespace std;
int n,m,x,cnt[1000005],w[1000005],ans[1000005];
int head[1000005],nxt[2000005],target[2000005],tot;
void add(int x,int y){tot++;nxt[tot]=head[x];head[x]=tot;target[tot]=y;
}
int dep[1000005],vis[1000005],f[1000005];
void dfs(int x,int fa){for(int i=head[x];i;i=nxt[i]){int y=target[i];if(y==fa) continue;f[y]=x;dep[y]=dep[x]+1;dfs(y,x);}
}
int find(int x){while(!vis[f[x]] && x){vis[x]=1;x=f[x];}vis[x]=1;return dep[x];
}
int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n;for(int i=1;i<=n;i++){cin>>x;add(x,i);cnt[x]++;cnt[i]++;}for(int i=1;i<=n;i++){if(cnt[i]==1) m++;}for(int i=1;i<=m;i++){cin>>w[i];}dfs(0,0);for(int i=m;i>=1;i--){ans[i]=find(w[i]);}for(int i=1;i<=m;i++){cout<<ans[i]<<'\n';}return 0;
}
C
注意到如果从最终状态往前推,每次能够进行的操作是唯一的。
然后瓶颈在于加快这个模拟过程。
不难发现,在大部分情况下,\((a,b) \to (a\bmod b,b)\)。
然后就可以每次判断能否这么做,直接搜索即可。
复杂度 \(O(log v)\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,a,b,c,d;
int solve(int a,int b,int c,int d,int val){if(!a || !b || a<c || b<d) return -1;if(a<b) swap(a,b),swap(c,d);if(b==d && a%b==c%b) return val+(a-c)/b;else return solve(a%b,b,c,d,val+a/b);
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>t;while(t--){cin>>c>>d>>a>>b;cout<<solve(a,b,c,d,0)<<'\n';} return 0;
}