AtCoder Beginner Contest 136 简要题解

文章目录

    • A
    • B
    • C
    • D
    • E
    • F

差点被ABC的题虐自闭啦
传送门

A

模拟
代码:

#include
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	#define gc getchar
	int ans=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return ans;
	#undef gc
}
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
int main(){
	int a=read(),b=read(),c=read();
	cout<<max(0,c+b-a);
	return 0;
}


B

模拟
代码:

#include
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	#define gc getchar
	int ans=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return ans;
	#undef gc
}
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
inline bool check(int x){
	int ret=0;
	while(x)x/=10,++ret;
	return ret&1;
}
int main(){
	int a=read();
	int cnt=0;
	for(ri i=1;i<=a;++i)if(check(i))++cnt;
	cout<<cnt;
	return 0;
}


C

模拟
代码:

#include
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	#define gc getchar
	int ans=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return ans;
	#undef gc
}
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=1e5+5;
int n,a[N];
int main(){
	bool f=1;
	n=read();
	for(ri i=1;i<=n;++i){
		a[i]=read();
		if(i==1){
			--a[i];
			continue;
		}
		if(a[i]<a[i-1]){f=0;break;}
		if(a[i]!=a[i-1])--a[i];
	}
	puts(f?"Yes":"No");
	return 0;
}


D

手玩一下发现 R L RL RL会形成死循环。
然后就双指针找出所有 R R R . . . R L L L . . . L RRR...RLLL...L RRR...RLLL...L然后统计答案即可。
代码:

#include
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	#define gc getchar
	int ans=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return ans;
	#undef gc
}
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=1e5+5;
char s[N];
int n;
inline void solve(int ql,int qr,int cl,int cr){
	for(ri i=1;i<cl;++i)cout<<0<<' ';
	cout<<(cl+1)/2+cr-(cr+1)/2<<' '<<cl-(cl+1)/2+(cr+1)/2<<' ';
	for(ri i=1;i<cr;++i)cout<<0<<' ';
}
int main(){
	scanf("%s",s+1);
	n=strlen(s+1);
	for(ri l=1,r;l<=n;l=r+1){
		r=l;
		while(r<n&&s[r+1]=='R')++r;
		int len=r-l+1;
		while(r<n&&s[r+1]=='L')++r;
		solve(l,r,len,r-l+1-len);
	}
	return 0;
}


E

考虑枚举 ∑ a i \sum a_i ai的约数 g g g是否能作为 g c d gcd gcd
然后用贪心来 c h e c k check check
首先将数组 a i % g a_i\%g ai%g从小到大排序。
然后找到最大的 t t t满足 ∑ i = 1 t a i % g ≤ k \sum_{i=1}^ta_i\%g\le k i=1tai%gk
最后看 ∑ i = t + 1 n g − a i % g \sum_{i=t+1}^ng-a_i\%g i=t+1ngai%g是否大于 k k k即可。
代码:

#include
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	#define gc getchar
	int ans=0;
	char ch=gc();
	while(!isdigit(ch))ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return ans;
	#undef gc
}
typedef long long ll;
typedef pair<int,int> pii;
const int mod=998244353;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=505;
int s=0,n,k,a[N];
inline bool check(int x){
	ll ss=0,sss=0;
	vector<int>s;
	for(ri i=1;i<=n;++i)s.push_back(a[i]%x),sss+=x-a[i]%x;
	sort(s.begin(),s.end());
	ss=s[0],sss-=x-s[0];
	for(ri i=1,up=s.size();i<up;++i){
		if(ss+s[i]>k)break;
		ss+=s[i],sss-=x-s[i];
	}
	return ss<=k&&sss<=k;
}
int main(){
	n=read(),k=read();
	for(ri i=1;i<=n;++i)a[i]=read(),s+=a[i];
	int ans=1;
	if(check(s))return cout<<s<<'\n',0;
	for(ri i=2;i*i<=s;++i){
		if(s!=s/i*i)continue;
		if(check(i))ans=max(ans,i);
		if(check(s/i))ans=max(ans,s/i);
	}
	cout<<ans;
	return 0;
}


F

考虑用扫描线+ b i t bit bit统计出每个点左上,左下,右上,右下各有多少点。
然后对于每个点分开统计贡献,即计算每个点在多少个矩形中出现。
这个计数可以利用之前处理出的信息+容斥得出。
详见代码:

#include
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	#define gc getchar
	int ans=0;
	char ch=gc();
	bool f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
	return f?ans:-ans;
	#undef gc
}
typedef long long ll;
typedef pair<int,int> pii;
const int mod=998244353;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)Mul(ret,a);return ret;}
const int N=2e5+5;
int n,vx[N],sx=0,vy[N],sy=0,clu[N],cld[N],cru[N],crd[N],pw[N];
pii a[N];
int bit[N];
inline int lowbit(const int&x){return x&-x;}
inline void update(int x,int v){for(;x<=n;x+=lowbit(x))Add(bit[x],v);}
inline int query(int x){int ret=0;for(;x;x-=lowbit(x))Add(ret,bit[x]);return ret;}
inline int query(int l,int r){return dec(query(r),query(l-1));}
int main(){
	n=read();
	pw[0]=1;
	for(ri i=1;i<=n;++i)pw[i]=add(pw[i-1],pw[i-1]);
	for(ri i=1;i<=n;++i){
		vx[i]=a[i].fi=read();
		vy[i]=a[i].se=read();
	}
	sort(vy+1,vy+n+1),sort(a+1,a+n+1);
	for(ri i=1;i<=n;++i){
		a[i].se=lower_bound(vy+1,vy+n+1,a[i].se)-vy;
		clu[i]=query(1,a[i].se-1);
		cld[i]=query(a[i].se+1,n);
		update(a[i].se,1);
	}
	memset(bit,0,sizeof(bit));
	for(ri i=n;i;--i){
		cru[i]=query(1,a[i].se-1);
		crd[i]=query(a[i].se+1,n);
		update(a[i].se,1);
	}
	int ans=0;
	for(ri i=1;i<=n;++i){
		int t=0;
		Add(t,pw[n-1]);
		Add(t,pw[n-1]);
		Dec(t,pw[clu[i]+cld[i]]);
		Dec(t,pw[cru[i]+crd[i]]);
		Dec(t,pw[clu[i]+cru[i]]);
		Dec(t,pw[cld[i]+crd[i]]);
		Add(t,pw[clu[i]]);
		Add(t,pw[cru[i]]);
		Add(t,pw[cld[i]]);
		Add(t,pw[crd[i]]);
		Add(ans,t-1);
	}
	cout<<ans;
	return 0;
}

你可能感兴趣的:(#,题解)