AtCoder Beginner Contest 172 A-E

A:模拟

#include 
using namespace std;
typedef long long ll;
const int M = 1e5+7;

int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	ll n;
  	cin>>n;
  	cout<<(n+n*n+n*n*n)<

B:直接比较。

#include 
using namespace std;
typedef long long ll;
const int M = 2e5+7;

char a[M],b[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>a>>b;
  	int n=strlen(a);
  	int nm=0;
  	for(int i=0;i

C:枚举a数组,快速找到最优的b数组的位置即可。

也可以双指针搞。

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll a[M],b[M],sm[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n,m,k;
  	cin>>n>>m>>k;
  	for(int i=1;i<=n;i++)cin>>a[i];
  	for(int i=1;i<=m;i++)cin>>b[i],sm[i]=sm[i-1]+b[i];
  	ll sa=0;
	  int mx=0;
	for(int i=0;i<=n;i++)
  	{
  		sa+=a[i];
  		if(sa>k)break;
  		int id=upper_bound(sm+1,sm+1+m,k-sa)-sm;
  		id--;
  		mx=max(mx,i+id);
	}
	cout<

D:

直接nlogn暴力即可。

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e7+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll nm[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n;
  	cin>>n;
  	for(int i=1;i<=n;i++)
  		for(int j=1;j<=n/i;j++)
  			nm[i*j]++;
  	ll ans=0;
  	for(int i=1;i<=n;i++)
  		ans+=nm[i]*i;
	cout<

E:容斥+组合数

先把a数组固定:即A(n,m)从m种选n个进行全排列。

然后b数组选出n个数,求出使得第i个数不为i的个数。再利用乘法原理即可求出结果。

难点在如何求出使从b数组选出n个数得第i个数不为i的个数。

用容斥处理即可:

第i个数为i的并集和。=   一个数不为i - 两个数不为i + 3个数不为i -……

然后用总排列减去这个就是从b数组选出n个数得第i个数不为i的个数。

#include 
using namespace std;
typedef long long ll;
const int M = 5e5+7;
const int mod=1e9+7;
ll qpow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b/=2;
	}
	return ans;
}

ll fac[M],inv[M];
ll f[M],dp[M];//错排 
ll A(int n,int m){
	return fac[m]*inv[m-n]%mod;
}
ll C(int n,int m){
	return fac[m]*inv[n]%mod*inv[m-n]%mod;
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n,m,N=5e5;
  	cin>>n>>m;fac[0]=inv[0]=1;
	for(int i=1;i<=m;i++)fac[i]=fac[i-1]*i%mod,inv[i]=qpow(fac[i],mod-2);
	f[2]=1;for(int i=3;i<=m;i++)f[i]=(f[i-1]+f[i-2])*(i-1)%mod;
	ll ans=A(n,m);
	//n个位置不同 
	for(int i=1;i<=n;i++)//至少几个位置相同
	{
	//	cout<< ans<<"  "<

 

你可能感兴趣的:(atcoder,数学---组合数学,数论——莫比乌斯/容斥)