C Stone Game
首先数目为 3 3 3 的石堆对于答案没有贡献,考虑目前数目为 1 1 1 和 2 2 2 的石堆的数目,如果二者都不为零,那么将两者合并一定最优,这样就得到了对于答案没有贡献的数目为 3 3 3 的石堆,如果只剩一堆,那么我们考虑将这一堆的 2 3 \frac{2}{3} 32 进行合并,这样剩余的 1 3 \frac{1}{3} 31 就能和新得到的进行合并,实现的时候需要注意边界的小细节,复杂度 O ( l o g n ) O(logn) O(logn)。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int x,y,z;
ll ans;
int main(){
#ifndef ONLINE_JUDGE
freopen("sample.in","r",stdin);
freopen("sample.out","w",stdout);
#endif
cin>>x>>y>>z;
while(x+y>1){
if(!x){
if(y==2){
ans+=4;
break;
}
ans+=y/3*2*2;
x=y/3,y-=y/3*2;
}
else if(!y){
if(x==2){
++ans;
break;
}
ans+=x/3;
y=x/3,x-=x/3*2;
}
else{
if(x>y){
ans+=y*2;
x-=y,y=0;
}
else{
ans+=x*2;
y-=x,x=0;
}
}
}
cout<<ans<<endl;
return 0;
}
D Fight against involution
考虑按右端点从小到大排序,这样左端点贪心的选择尽可能小的,当 r i r_i ri 相同的时候两个人所选择的点也必须一样,实现的时候可以 l i l_i li 作为第二关键字从大到小排序,复杂度 O ( n l o g n ) O(nlogn) O(nlogn)。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
struct node{
int l,r;
};
int n;
node c[N];
bool cmp(node x,node y){
if(x.r==y.r) return x.l>y.l;
return x.r<y.r;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("sample.in","r",stdin);
freopen("sample.out","w",stdout);
#endif
cin>>n;
for(int i=1;i<=n;++i) cin>>c[i].l>>c[i].r;
sort(c+1,c+n+1,cmp);
ll ans=0;
int lst=0;
for(int i=1;i<=n;++i){
if(c[i].r==c[i-1].r){
ans+=lst;
}
else{
lst=max(lst,c[i].l);
ans+=lst;
}
}
cout<<ans<<endl;
return 0;
}
G Xor Transformation
唯一约束条件是 A A A 必须要比 X X X 更小,考虑将 X X X 最高位以下为零的二进制位补 1 1 1 ,然后与 X x o r Y X~xor~Y X xor Y相异或即可,显然选择的数都小于该状态下的 X X X,复杂度 O ( l o g X ) O(logX) O(logX)。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=105;
ll x,y;
int cnt1,cnt2;
ll a[N],b[N];
int main(){
#ifndef ONLINE_JUDGE
freopen("sample.in","r",stdin);
freopen("sample.out","w",stdout);
#endif
cin>>x>>y;
while(x){
a[++cnt1]=x&1;
x>>=1;
}
while(y){
b[++cnt2]=y&1;
y>>=1;
}
ll ans=0,res=0;
for(int i=cnt1;i>=1;--i){
if(a[i]==0){
a[i]^=1;
ans^=(1ll<<(i-1));
}
}
for(int i=cnt1;i>=1;--i){
if(a[i]!=b[i]){
a[i]^=1;
res^=(1ll<<(i-1));
}
}
cout<<2<<endl;
cout<<ans<<" "<<res<<endl;
return 0;
}
M Cook Pancakes!
#include<bits/stdc++.h>
using namespace std;
int n,k;
int main(){
#ifndef ONLINE_JUDGE
freopen("sample.in","r",stdin);
freopen("sample.out","w",stdout);
#endif
cin>>n>>k;
if((n*2)%k) cout<<max(2,n*2/k+1)<<endl;
else cout<<max(2,n*2/k);
return 0;
}