Codeforces Round 895 (Div. 3)
Codeforces Round 895 (Div. 3)
A - Two Vessels
思路:找到差值,让a,b向中间靠
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve(){ int a,b,c;cin>>a>>b>>c; int s=abs(a-b); s=(s+c-1)/c; cout<<(s+1)/2<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
B - The Corridor or There and Back Again
思路:走到x后的y秒内要走回x,走到最远的距离为x+(y-1)/2,找到最小的距离
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve(){ int n;cin>>n; int x,y,ans=INF; for(int i=0;i<n;++i){ cin>>x>>y; y--; y/=2; ans=min(ans,x+y); } cout<<ans<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
C - Non-coprime Split
思路:暴力枚举l~r,若该数为非质数即可
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve(){ int l,r; cin>>l>>r; if(r<=3)cout<<-1<<'\n'; else{ if(l==r&&l%2){ for(int i=2;i<=l/i;++i){ if(l%i==0){ cout<<i<<' '<<l-i<<'\n';return ; } } cout<<-1<<'\n'; }else if(l==r&&l%2==0){ cout<<2<<' '<<l-2<<'\n'; }else{ int s=r; if(s%2)s--; cout<<2<<' '<<s-2<<'\n'; } } } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
D - Plus Minus Permutation
思路:x和y的倍数的个数即为分别加的p的个数,再减去x和y的公共部分个数即最小公倍数的倍数个数,让x部分加最大的数,y部分加最小的部分
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve(){ int n,x,y; cin>>n>>x>>y; int a=n/x,b=n/y; int c=__gcd(x,y); c=x/c*y; c=n/c; a-=c,b-=c;//cout<<a<<' '<<b<<' '; cout<<(n*n-(n-a)*(n-a+1)-(b+1)*b+n)/2<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
E - Data Structures Fan
思路:将一段中的数翻转,即将all0异或val1和val0,all1异或val0和val1(val0表示这一段所有为0的数异或和,val1同理,all0表示所有为0的数异或和,all1同理);去掉或添加一个数的操作都为异或这个数。
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve(){ int n;cin>>n; vector<int>a(n+1),a1(n+1),a0(n+1); for(int i=1,x;i<=n;++i){ cin>>a[i]; } string s;cin>>s; s=' '+s; int all1=0,all0=0; for(int i=1;i<=n;++i){ if(s[i]=='1'){ all1^=a[i]; a1[i]=a[i]^a1[i-1]; a0[i]=a0[i-1]; }else{ all0^=a[i]; a0[i]=a[i]^a0[i-1]; a1[i]=a1[i-1]; } } int q;cin>>q; int op,l,r; while(q--){ cin>>op; if(op==1){ cin>>l>>r; int b0=a0[r]^a0[l-1]; int b1=a1[r]^a1[l-1]; all1^=b1,all1^=b0; all0^=b0,all0^=b1; }else{ cin>>l; if(l==0)cout<<all0<<' '; else cout<<all1<<' '; } } cout<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
F - Selling a Menagerie
思路:若i在a[i]前卖掉,则得2c[i],否则得c[i];那么建立i到a[i]的有向边,入度为0的点卖掉可得2c[i],再将卖掉得点进行删边,最后只可能会剩下环,对于一个环中,最少只能让一个点得c[i],环上其余点得2c[i],那么dfs找到环上c最小的点即可
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; int mi,p; vector<int>c(N),to(N),st(N); void dfs(int u){ if(c[u]<mi){ mi=c[u]; p=u; } st[u]=1; if(!st[to[u]]){ dfs(to[u]); } } void solve(){ int n;cin>>n; vector<int>d(n+1); for(int i=1,x;i<=n;++i){ cin>>x; to[i]=x; d[x]++; } for(int i=1;i<=n;++i)cin>>c[i]; queue<int>q; st=vector<int>(n+1,0); for(int i=1;i<=n;++i){ if(!d[i]){ st[i]=1; q.push(i); } } vector<int>ans; while(q.size()){ int t=q.front();q.pop(); ans.push_back(t); if(!(--d[to[t]])&&!st[to[t]]){ st[to[t]]=1; q.push(to[t]); } } for(int i=1;i<=n;++i){ if(!st[i]){ mi=INF; dfs(i); int t=to[p]; while(t!=p){ ans.push_back(t); t=to[t]; } ans.push_back(p); } } for(auto v:ans)cout<<v<<' ';cout<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; while(T--){ solve(); } return 0; }
G - Replace With Product
思路:对于一段[l,r]的数,有n个数,积为p,若要在该段增加一个数,最小的情况是增加一个2,那么新的积为2p,新的和为p+(n-2)+2=p+n,增加该数更好的话:2p>p+n,即p>n;新的积为2p,则2p>2n;
l和r为第一个和最后一个非一的位置,那么当n为r-l+1时,即最大为2e5,若积大于4e5,则答案一定为l和r;若积小于4e5,有贡献的数最小为2,即最多有18个非一的数,那么直接暴力求所有区间
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const double eps=1e-6; void solve(){ int n;cin>>n; vector<int>a(n+1); for(int i=1;i<=n;++i)cin>>a[i]; int l=1,r=n; while(a[l]==1&&l<=n)l++; while(a[r]==1&&r>=0)r--; if(l>=r){ cout<<1<<' '<<1<<'\n';return ; } int s=1; for(int i=l;i<=r;++i){ s*=a[i]; if(s>2*(r-l+1)){ cout<<l<<' '<<r<<'\n';return ; } } vector<int>b,pre(n+1); for(int i=1;i<=n;++i){ pre[i]=pre[i-1]+a[i]; if(a[i]>1)b.push_back(i); } int ansl,ansr,ma=0; for(int t,i=0;i<b.size();++i){ t=1; for(int j=i;j<b.size();++j){ t*=a[b[j]]; int x=pre[n]-pre[b[j]]+pre[b[i]-1]+t; if(x>ma){ ma=x; ansl=b[i],ansr=b[j]; } } } cout<<ansl<<' '<<ansr<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T; while(T--){ solve(); } return 0; }