Educational Codeforces Round 86 [Rated for Div. 2]

题目链接

‘Educational Codeforces Round 86 [Rated for Div. 2]’

A

思路

水题,分三种情况就可以了

代码实现
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define vi vector<int>
#define vll vector<vll>
#define pii pair<int,int>
#define pll pair<ll,ll>
inline bool isprime(ll num)
{if(num==2||num==3)return true;
if(num%6!=1&&num%6!=5)return false;
for(int i=5;1ll*i*i<=num;i+=6){if(num%i==0||num%(i+2)==0)return false;}
return true;}
const int mod = 1e9+7;
inline ll mul(ll a,ll b,ll c){return (a*b-(ll)((ld)a*b/c)*c+c)%c;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll g = exgcd(b,a%b,y,x);y-=a/b*x;return g;}
inline ll quick_pow(ll a,ll b,ll mod){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll quick_pow(ll a,ll b){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll inv(ll x){return quick_pow(x,mod-2);}
inline ll inv(ll x,ll mod){return quick_pow(x,mod-2,mod);}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int x,y;
		scanf("%d %d",&x,&y);
		int a,b;
		scanf("%d %d",&a,&b);
		ll ans = 1ll*(x+y)*a;
		if(x<y)swap(x,y);
		ans=min(ans,1ll*a*(x-y)+1ll*y*b);
		ans=min(ans,1ll*a*(x-y)+1ll*x*b);
		printf("%lld\n",ans);
	}
}

B

思路

不是全0或者全1输出010101就好,否则输出全0或者全1

代码实现
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
inline bool isprime(ll num)
{if(num==2||num==3)return true;
if(num%6!=1&&num%6!=5)return false;
for(int i=5;1ll*i*i<=num;i+=6){if(num%i==0||num%(i+2)==0)return false;}
return true;}
const int mod = 1e9+7;
inline ll mul(ll a,ll b,ll c){return (a*b-(ll)((ld)a*b/c)*c+c)%c;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll g = exgcd(b,a%b,y,x);y-=a/b*x;return g;}
inline ll quick_pow(ll a,ll b,ll mod){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll quick_pow(ll a,ll b){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll inv(ll x){return quick_pow(x,mod-2);}
inline ll inv(ll x,ll mod){return quick_pow(x,mod-2,mod);}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
string s;
void solve(string s){
	int n=s.size();
	bool flag = true;
	for(int i=1;i<s.size();i++){
		if(s[i]!=s[0]){
			flag=false;
			break;
		}
	}
	if(flag){
		cout<<s<<endl;
	}else{
		for(int i=0;i<s.size();i++){
			cout<<"01";
		}
		cout<<endl;
	}
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		cin>>s;
		solve(s);
	} 
}

C

思路

用r-l+1减去相等的,相等的怎么算呢?其实就是klcm(a,b)~klcm(a,b)+max(a,b),用l/lcm,r/lcm找出上界下界,讨论边缘情况,中间的直接乘上max(a,b)就是答案

代码实现
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
inline bool isprime(ll num)
{if(num==2||num==3)return true;
if(num%6!=1&&num%6!=5)return false;
for(int i=5;1ll*i*i<=num;i+=6){if(num%i==0||num%(i+2)==0)return false;}
return true;}
const int mod = 1e9+7;
inline ll mul(ll a,ll b,ll c){return (a*b-(ll)((ld)a*b/c)*c+c)%c;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll g = exgcd(b,a%b,y,x);y-=a/b*x;return g;}
inline ll quick_pow(ll a,ll b,ll mod){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll quick_pow(ll a,ll b){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll inv(ll x){return quick_pow(x,mod-2);}
inline ll inv(ll x,ll mod){return quick_pow(x,mod-2,mod);}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll lcm(ll a,ll b){return a*b/gcd(a,b);}
void solve(){
	int a,b,q;
	scanf("%d %d %d",&a,&b,&q);
	if(a<b)swap(a,b);
	while(q--){
		ll l,r;
		scanf("%lld %lld",&l,&r);
		ll ans = r-l+1;
		ll lc = lcm(a,b);
		ll mi = (l-1)/lc;
		ll mx = r/lc;
		ans-=max(0ll,mx-mi-1)*a;
		ans-=max(0ll,min(r,mi*lc+a-1)-max(l,mi*lc)+1);
		if(mi!=mx)ans-=max(0ll,min(r,mx*lc+a-1)-max(l,mx*lc)+1); 
		printf("%lld ",a==b?0:ans);
	}
	printf("\n");
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--)solve();
}

D

思路

用set把长度存起来,满足要求的就相当于在第二个数组中找出大于1,2,3,4,5的位置,然后再到第一个数组中寻找数即可

代码实现
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define vi vector<int>
#define vll vector<ll>
#define pii pair<int,int>
#define pll pair<ll,ll>
inline bool isprime(ll num)
{if(num==2||num==3)return true;
if(num%6!=1&&num%6!=5)return false;
for(int i=5;1ll*i*i<=num;i+=6){if(num%i==0||num%(i+2)==0)return false;}
return true;}
const int mod = 1e9+7;
inline ll mul(ll a,ll b,ll c){return (a*b-(ll)((ld)a*b/c)*c+c)%c;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll g = exgcd(b,a%b,y,x);y-=a/b*x;return g;}
inline ll quick_pow(ll a,ll b,ll mod){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll quick_pow(ll a,ll b){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll inv(ll x){return quick_pow(x,mod-2);}
inline ll inv(ll x,ll mod){return quick_pow(x,mod-2,mod);}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll lcm(ll a,ll b){return a*b/gcd(a,b);}
const int N =  2e5+10;
vi v[N];
int a[N],b[N];
int mi[N];
multiset<int>s;
int cmp(int a,int b){
	return a>b;
}
int main(){
	int n,k;
	scanf("%d %d",&n,&k);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		s.insert(a[i]);
	}
	for(int i=0;i<k;i++)scanf("%d",&b[i]);
	sort(b,b+k);
	int cnt = 0;
	while(s.size()){
		set<int>::iterator it;
		int p = 1;
		while(1){
		int pos = lower_bound(b,b+k,p)-b;
		pos = k-pos;
	    it = s.upper_bound(pos);
		if(it==s.begin())break;
		it--;
		v[cnt].push_back(*it);
		s.erase(it);
		p++;
	    }
	    cnt++;
	}
	printf("%d\n",cnt);
	for(int i=0;i<cnt;i++){
		printf("%d ",v[i].size());
		for(auto k:v[i]){
			printf("%d ",k);
		}
		printf("\n");
	}
}

E

思路

满足第一个条件的要求就是每行至少有一个棋子或者每列至少有一个棋子,我们考虑每行至少有一个棋子,然后得到答案后2就是真正的答案。
满足第二个条件,我们考虑每行至少有1个棋子,那么有k个可以互相共计,那么就是有n-k有棋子,其他的为空,转化一下其实就是把n个不同的球放出n-k个相同的盒子当中,这个就是第二类斯特林数,不会的自行上百度学习即可。
最后答案就是2
C(n,n-k)*S(n,n-k);
S代表斯特林数

代码实现
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
inline bool isprime(ll num)
{if(num==2||num==3)return true;
if(num%6!=1&&num%6!=5)return false;
for(int i=5;1ll*i*i<=num;i+=6){if(num%i==0||num%(i+2)==0)return false;}
return true;}
const int mod = 998244353;
inline ll mul(ll a,ll b,ll c){return (a*b-(ll)((ld)a*b/c)*c+c)%c;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll g = exgcd(b,a%b,y,x);y-=a/b*x;return g;}
inline ll quick_pow(ll a,ll b,ll mod){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll quick_pow(ll a,ll b){ll res=1;while(b){if(b&1)res=mul(res,a,mod);a=mul(a,a,mod);b>>=1;}return res;}
inline ll inv(ll x){return quick_pow(x,mod-2);}
inline ll inv(ll x,ll mod){return quick_pow(x,mod-2,mod);}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll lcm(ll a,ll b){return a*b/gcd(a,b);}

const int N = 2e5+10;
int fac[N];
ll C(int n,int m){
	if(n<m||n<0||m<0)return 0;
	return 1ll*fac[n]*quick_pow(1ll*fac[m]*fac[n-m]%mod,mod-2)%mod;
}
int main(){
	ll n,k;
	cin>>n>>k;
	fac[0]=1;
	for(int i=1;i<N;i++)fac[i]=1ll*fac[i-1]*i%mod;
	if(k>=n)return 0*printf("0\n");
	if(k==0)return 0*printf("%d\n",fac[n]);
	ll ans = 0;
	for(int i=0;i<=n-k;i++)
	ans=(ans+1ll*quick_pow(mod-1,i)*C(n-k,i)%mod*quick_pow(n-k-i,n)%mod)%mod;
	printf("%lld\n",2ll*ans%mod*C(n,n-k)%mod);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值