A. To Zero
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,k;
cin>>n>>k;
int ans=0;
if(n%2==1)
{
n-=k;
ans++;
}
k--;
cout<<ans+n/k+(n%k>0)<<"\n";
}
return 0;
}
B. Array Recoloring
- 若\(k \neq 1\),则选取最大的k+1个数,可以证明一定能构造出可行解
#include <bits/stdc++.h>
using namespace std;
int a[5005];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
if(k!=1)
{
sort(a+1,a+n+1);
long long ans=0;
for(int i=n;i>=n-k;i--)
{
ans+=a[i];
}
cout<<ans<<"\n";
}
else
{
cout<<max(a[1]+*max_element(a+2,a+n+1),a[n]+*max_element(a+1,a+n))<<"\n";
}
}
return 0;
}
C. Two Colors
#include <bits/stdc++.h>
using namespace std;
long long a[200005];
long long s[200005];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>a[i];
if(a[i]==n)
{
a[i]--;
}
}
sort(a+1,a+m+1);
for(int i=1;i<=m;i++)
{
s[i]=s[i-1]+a[i];
}
long long ans=0;
for(int i=1;i<=m;i++)
{
int j=lower_bound(a+i+1,a+m+1,n-a[i])-a;
ans=ans+2*((m-j+1)*(a[i]-n+1)+s[m]-s[j-1]);
}
cout<<ans<<"\n";
}
return 0;
}
D. Equalization
#include <bits/stdc++.h>
using namespace std;
#define int long long
int f[60][60][60],g[60][60];
map<int,int>q;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
f[0][0][0]=0;
g[0][0]=0;
for(int k=1;k<60;k++)
{
for(int i=0;i<60;i++)
{
for(int j=0;j<60;j++)
{
f[i][j][k]=min(f[i][j][k],f[i][j][k-1]);
if(i>=k)
{
f[i][j][k]=min(f[i][j][k],f[i-k][j][k-1]+(1ll<<k));
}
if(j>=k)
{
f[i][j][k]=min(f[i][j][k],f[i][j-k][k-1]+(1ll<<k));
}
g[i][j]=min(g[i][j],f[i][j][k]);
}
}
}
int T;
cin>>T;
while(T--)
{
int x,y;
cin>>x>>y;
int ans=LLONG_MAX;
q.clear();
for(int i=0;i<60;i++)
{
if(q.find(x>>i)==q.end())
{
q[x>>i]=i;
}
}
for(int i=0;i<60;i++)
{
if(q.find(y>>i)!=q.end())
{
ans=min(ans,g[i][q[y>>i]]);
}
}
cout<<ans<<"\n";
}
return 0;
}
E. XOR Matrix
- 别总是反思了,先夸一夸自己:我觉得你做这道题的过程已经很完美了,只是纠结modint耗费了一些时间。倘若自己的modint模板完备一点或者直接在赛场上扩展modint或者干脆像原来一样手动取模,说不定都能赶在比赛结束之前通过这道题
- 赛后更新了modint版本,扩展了输入输出流、除法运算、乘方运算、右移运算、&运算
- 突然发现多年以来不知道为什么自己一直有这样一个误区:求乘法逆元要把mod-2的值手动算出来。mod是常量不能修改不假,可是你计算mod-2又没有修改mod……
- 考虑到memset的本质,它也可以用来初始化mint数组
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
int power(int n,int p)
{
if(p==0)
{
return 1;
}
long long tmp=power(n,p/2);
if(p%2==1)
{
return tmp*tmp%mod*n%mod;
}
return tmp*tmp%mod;
}
struct mint
{
unsigned int x;
mint(int o=0)
{
x=o;
}
mint operator =(int o)
{
return x=o,*this;
}
mint operator +=(mint o)
{
return x=(x+o.x)%mod,*this;
}
mint operator -=(mint o)
{
return x=(x-o.x+mod)%mod,*this;
}
mint operator *=(mint o)
{
return x=1ll*x*o.x%mod,*this;
}
mint operator /=(mint o)
{
return x=1ll*x*power(o.x,mod-2)%mod,*this;
}
mint operator &=(mint o)
{
return x=(x&o.x),*this;
}
mint operator >>=(mint o)
{
return x=(x>>o.x),*this;
}
friend bool operator ==(mint a,mint b)
{
return a.x==b.x;
}
friend mint operator +(mint a,mint b)
{
return a+=b;
}
friend mint operator -(mint a,mint b)
{
return a-=b;
}
friend mint operator *(mint a,mint b)
{
return a*=b;
}
friend mint operator /(mint a,mint b)
{
return a/=b;
}
friend mint operator &(mint a,mint b)
{
return a&=b;
}
friend mint operator >>(mint a,mint b)
{
return a>>=b;
}
};
istream& operator >>(istream& is,mint &o)//mint 也要加引用,否则赋值无效
{
is>>o.x;
return is;
}
ostream& operator <<(ostream& os,mint o)
{
os<<o.x;
return os;
}
/*
运算符重载通常有两种方式:成员函数和非成员函数。对于<<运算符来说,通常建议作为非成员函数来重载,
因为左操作数应该是ostream对象,比如cout,而成员函数的话,左操作数必须是该类的对象,这显然不合适。
*/
//C++标准库中的流对象不可拷贝
mint power(mint n,mint p)
{
if(p==0)
{
return 1;
}
mint tmp=power(n,p>>1);
if((p&1)==1)
{
return tmp*tmp*n;
}
return tmp*tmp;
}
mint f[30][16];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
mint n,m,a,b;
cin>>n>>m>>a>>b;
memset(f,0,sizeof(f));
f[29][0]=1;
mint sum=0;
for(int i=29;i>=0;i--)
{
for(int j=0;j<16;j++)
{
int p[]={j&1,(j>>1)&1,(j>>2)&1,(j>>3)&1};
for(int k=0;k<16;k++)
{
int q[]={k&1,(k>>1)&1,(k>>2)&1,(k>>3)&1};
if(q[3]!=(q[0]^q[1]^q[2]))
{
continue;
}
bool pd=true;
for(int l=0;l<2;l++)
{
if((((a>>i)&1)==0)&&p[l]==0&&q[l]==1)
{
pd=false;
break;
}
}
for(int l=2;l<4;l++)
{
if((((b>>i)&1)==0)&&p[l]==0&&q[l]==1)
{
pd=false;
break;
}
}
if(pd==false)
{
continue;
}
int st=0;
for(int l=0;l<2;l++)
{
if(p[l]==1||(((a>>i)&1)==1)&&p[l]==0&&q[l]==0)
{
st+=(1<<l);
}
}
for(int l=2;l<4;l++)
{
if(p[l]==1||(((b>>i)&1)==1)&&p[l]==0&&q[l]==0)
{
st+=(1<<l);
}
}
if(i)
{
f[i-1][st]+=f[i][j];
}
else
{
sum+=f[i][j];
}
}
}
}
sum-=(a+1)*(b+1);
sum/=4;
cout<<(a+1)*(b+1)+(b+1)*a*(a+1)/2*(power(2,n)-2)+(a+1)*b*(b+1)/2*(power(2,m)-2)+sum*(power(2,n)-2)*(power(2,m)-2)<<endl;
}
return 0;
}