AtCoder Beginner Contest 152 题解

传送门:

A

int main(){
	int n, m; cin>>n>>m;
	if(n>m) puts("No");
	else puts("Yes");
    return 0;
}

B

int main(){
	int a, b; cin>>a>>b;
	if(a>b) swap(a, b);
	
	int ans=0;
	while(b--){
		ans=ans*10+a;
	}
	cout<<ans;
    return 0;
}

C

树状数组维护一下即可

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=2e5+5;
int tr[N];

int lowbit(int x){return x&-x;}

void modify(int p, int v){
	for(;p<N; p+=lowbit(p)) tr[p]+=v;
}

int query(int p){
	int res=0;
	for(;p;p-=lowbit(p)) res+=tr[p];
	return res;
}

int main(){
	int n; read(n);
	
	int cnt=0;
	rep(i,1,n){
		int k; read(k);
		modify(k, 1);
		if(query(k)==1) cnt++;
	}	
	cout<<cnt;
    return 0;
}

D

(f[i][j]) 表示首为 (i) 尾为 (j) 的数的个数。
(ans = sum_{i=0}^9sum_{j=0}^9 f[i][j] imes f[j][i])

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

int f[10][10];

int main(){
	int n; cin>>n;
	rep(i,1,n){
		string si=to_string(i);
		f[si[0]-'0'][si[si.size()-1]-'0']++;
	}
	
	int res=0;
	rep(i,0,9) rep(j,0,9) res+=f[i][j]*f[j][i];
	cout<<res<<endl;
	
    return 0;
}

E

直接用py卡过去了orz

def gcd(a, b):
    return b if a%b==0 else gcd(b, a%b)


mod=int(1e9+7)
n=int(input())

a=[int(i) for i in input().split()]
res=1
for i in a:
    res*=i//gcd(i, res)
print(sum(res//i for i in a)%mod)

F

容斥原理 + 树上路径经典操作

考虑到直接统计十分困难,但是注意到对于每个约束的反面较为容易处理,所以我们使用容斥原理来统计。

下面我们的任务是求 (M) 个约束中相应的 (u,v) 路径所涉及的边数的并。
我们用 (path_i) 表示从根节点(我们不妨将点 (1) 记为根节点)到 (i) 所经过的点集(我们用二进制来表示)
那么 (u,v) 间路径所涉及的点就是 (path_u oplus path_v) 了。

注意:用 1<<x 表示 (2^x) 时如果 (x) 较大需要这样写:1LL<<x

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

#define int long long

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=55;

bool vis[N]; // vis id of edge
int n, m;

struct node{
	int next, to;
}e[N<<1];

int h[N],tot;
void add(int u, int v){
	e[tot].to=v, e[tot].next=h[u], h[u]=tot++;
}

int path[N], need[N];

void dfs(int u, int fa, int prev){
	path[u]|=prev;
	prev=path[u];
	for(int i=h[u]; ~i; i=e[i].next){
		int go=e[i].to;
		if(go==fa) continue;
		dfs(go, u, prev);
	}
}

int lowbit(int x){return x&-x;}
int calc(int x){
	int res=0;
	while(x) x-=lowbit(x), res++;
	return res;
}

signed main(){
	memset(h, -1, sizeof h);
	read(n);
	rep(i,1,n-1){
		int u, v; read(u), read(v);
		add(u, v), add(v, u);
	}
	
	// init
	rep(i,1,n) path[i]=1LL<<i;
	dfs(1, 0, 0); 
	rep(i,1,n) debug(path[i]);
	
	read(m);
	rep(i,0,m-1){
		int u, v; read(u), read(v);
		need[i]=path[u]^path[v];
	}
	
	int res=0;
	for(int i=0; i<(1<<m); i++){
		int sign=1, free=n-1, cnt=0;
		rep(j,0,m-1) if(i>>j&1){
			sign*=-1;
			cnt|=need[j];
		}
		free-=calc(cnt);
		res+=sign*(1LL<<free);
	}
	
	cout<<res<<endl;
	
	return 0;
}
原文地址:https://www.cnblogs.com/Tenshi/p/14897092.html