Educational Codeforces Round 176

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;
}
posted @ 2025-03-19 17:45  D06  阅读(40)  评论(0)    收藏  举报
//雪花飘落效果