A
题解:显然就拼一下 $a,b$ 然后再把 $c$ 用完,记得判一下 $a=b$ 的特殊情况。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+3; void Solve() { ll a,b,c,s;cin>>a>>b>>c; cout<<min(a,b)*2+c*2+(a!=b)<<endl; } int main() { int T;T=1; while(T--)Solve(); return 0; }View Code
B
题解:首先观察到,如果 $k$ 足够大,一定是 -1
然后就显然就是把 $A$ 到 $B$ 的删一部分,$B$ 到 $C$ 接着删一部分。
然后考虑从小枚举到大,自然可以双指针
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+3; ll n,m,ta,tb,k,a[N],b[N]; void Solve() { cin>>n>>m>>ta>>tb>>k;ll s=0; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=m;i++)cin>>b[i]; if(k>=min(n,m)){cout<<"-1"<<endl;return;} for(int i=1,j=1;i<=k+1&&j<=m;i++) { ll x=a[i]+ta,p=k-(i-1); while(j<=m&&b[j]<x)j++; if(b[j]<x||j+p>m){cout<<"-1"<<endl;return;} s=max(s,b[j+p]+tb); } cout<<s<<endl; } int main() { int T;T=1; while(T--)Solve(); return 0; }View Code
C
题解:这是一种小于 $3n$ 常数也小的方法
从中间劈开,向两边分开搞。
比如说左边处理到第 $l$ 下标时,就先把值为 $l$ 的搞到 $n$ 去,然后再搞过来。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+3; ll n,a[N],p[N]; vector<pair<ll,ll> >s; void Change(ll x,ll y) { s.push_back(make_pair(x,y)); ll sx=a[x],sy=a[y]; swap(a[x],a[y]);swap(p[sx],p[sy]); } void Solve() { cin>>n;s.clear(); for(int i=1;i<=n;i++)cin>>a[i],p[a[i]]=i; for(int l=n/2,r=n/2+1;l>0;l--,r++) { if(a[l]!=l) { if(p[l]>l)Change(1,p[l]); Change(p[l],n);Change(l,p[l]); } if(a[r]!=r) { if(p[r]<r)Change(p[r],n); Change(1,p[r]);Change(p[r],r); } } cout<<s.size()<<endl; for(int i=0;i<s.size();i++)cout<<s[i].first<<" "<<s[i].second<<endl; } int main() { int T;T=1; while(T--)Solve(); return 0; }View Code
D
题解:太水了!
分成两类,一类 $a_i<b_i$ 另一类 $a_i>b_i$ 然后分别排序即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+3; ll n,a[N],b[N]; struct Nod{ll x,y,id;}c[N],d[N]; bool Cmp(Nod a,Nod b){return a.x>b.x;} bool Dmp(Nod a,Nod b){return a.x<b.x;} void Solve() { cin>>n;ll C=0,D=0; for(int i=1;i<=n;i++)cin>>a[i]>>b[i]; for(int i=1;i<=n;i++) { if(a[i]<b[i])c[++C].x=a[i],c[C].y=b[i],c[C].id=i; else d[++D].x=a[i],d[D].y=b[i],d[D].id=i; } sort(c+1,c+C+1,Cmp);sort(d+1,d+D+1,Dmp); cout<<max(C,D)<<endl; if(C>D)for(int i=1;i<=C;i++)cout<<c[i].id<<" "; else for(int i=1;i<=D;i++)cout<<d[i].id<<" "; } int main() { int T;T=1; while(T--)Solve(); return 0; }View Code
E
题解:就将 $t$ 数组排序,然后对应项做差分两类一类减一类加,然后就做完了。
注意边界条件即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+3; ll n,b[N],c[N],d[N]; vector<tuple<ll,ll,ll> >s; struct Nod{ll x,id;}a[N]; bool Cmp(Nod a,Nod b){return a.x<b.x;} void Change(ll x,ll y,ll z) { a[x].x+=z;a[y].x-=z; s.push_back(make_tuple(a[x].id,a[y].id,z)); } void Solve() { cin>>n;ll o=0,C=0,D=0;s.clear(); for(int i=1;i<=n;i++)cin>>a[i].x,a[i].id=i,o+=a[i].x; for(int i=1;i<=n;i++)cin>>b[i],o-=b[i]; if(o!=0){cout<<"NO"<<endl;return;} sort(b+1,b+n+1);sort(a+1,a+n+1,Cmp); for(int i=1;i<=n;i++)if(a[i].x<b[i])c[++C]=i;else d[++D]=i; for(int i=1,j=1;i<=C&&j<=D;) { ll x=c[i],y=d[j],sx=b[x]-a[x].x,sy=a[y].x-b[y]; if(sx==0){i++;continue;}if(sy==0){j++;continue;} ll d=(a[y].x-a[x].x)/2; if(d<=0){cout<<"NO"<<endl;return;} Change(x,y,min(d,min(sx,sy))); } cout<<"YES"<<endl<<s.size()<<endl; for(int i=0;i<s.size();i++) cout<<get<0>(s[i])<<" "<<get<1>(s[i])<<" "<<get<2>(s[i])<<endl; } int main() { int T;T=1; while(T--)Solve(); return 0; }View Code
F
题解:神仙题
首先讲奇数个1转化为在二进制中每遇到一个1就取反。然后你将和转化为正数,方便操作。
然后你就贪心的你就统计一下当前位为某些数的最高位的权值和。如果对答案有作用,就进行操作。
为了无后效性,从低到高枚举即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+3; ll n,a[N],b[N]; void Solve() { cin>>n;ll o=0,S=0; for(int i=1;i<=n;i++)cin>>a[i]>>b[i],o+=a[i]; if(o<0)for(int i=1;i<=n;i++)a[i]=-a[i]; for(int j=0;j<62;j++) { ll s=0,p=(ll)1<<j; for(int i=1;i<=n;i++)if(63-__builtin_clzll(b[i])==j)s+=a[i]; if(s>0){S+=p;for(int i=1;i<=n;i++)if(b[i]&p)a[i]=-a[i];} } cout<<S<<endl; } int main() { int T;T=1; while(T--)Solve(); }View Code
标签:typedef,int,题解,ll,Global,Codeforces,long,Nod,Round From: https://www.cnblogs.com/Hanghang007/p/17178392.html