C题
签到题
D题
思路:
a·(a + 1)b | c····(c + 1)···d⇔(c−1)!b·!| (a−1)!d!
定义p的Fp(x) = y,y是x关于质数p的最大因子个数
当且仅当Fp(a)<=Fp(b)时有a|b.
我们可以先得到107以内的质数,然后计算Fp(x!)得到答案
#include<iostream>
#include <stdlib.h>
#include <vector>
#include<stack>
#include <string>
#include<queue>
#include <set>
#include<stdbool.h>
#include <cmath>
using namespace std;
typedef long long ll;
const ll maxn = 10000007; // 表长
ll prime[maxn], pNum = 0; // prime记录素数,pNum记录素数个数
bool p[maxn] = { false }; // p记录当前数是否被筛去
void Prime(ll n) // 查找记录2-n的素数
{
for (ll i = 2; i <= n; i++)
{
if (p[i] == false) // 如果未被筛过,则为素数
prime[pNum++] = i;
for (ll j = 0; j < pNum; j++)
{
if (i * prime[j] > n) // 当要标记的合数超出范围时跳出
break;
p[i * prime[j]] = true; // 将已经记录的素数的倍数进行标记
if (i % prime[j] == 0) //关键步骤
break;
}
}
}
ll Fp(ll p, ll x)
{
ll num = 0;
for (ll i = p; i <= x; i = i * p)
{
num += x / i;
}
return num;
}
int main()
{
Prime(maxn);
ll t, a, b, c, d;
ll flag;
cin >> t;
while (t--)
{
flag = 1;
cin >> a >> b >> c >> d;
for (ll i = 2; i < maxn; i++)
{
if (d < i && c < i && b < i && a < i)break;
else
{
if (!p[i])
{
if ((Fp(i, a - 1) + Fp(i, d)) < (Fp(i, b) + Fp(i, c - 1)))
{
flag = 0;
break;
}
}
}
}
if (flag)cout << "Yes" << endl;
else cout << "No" << endl;
}
}
E题
思路:通过LCA求路径,然后判断路径长度的奇偶。
#include<iostream>
#include <stdlib.h>
#include <vector>
#include<stack>
#include <string>
#include<queue>
#include <set>
#include<stdbool.h>
#include <cmath>
using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 7, M = N * 2;
int pre[N], e[M], ne[M], vis[N], head[N], dis[N], w[M], cnt;
int depth[N], fa[N][16];
void add(int a, int b, int c)
{
e[cnt] = b, ne[cnt] = head[a], w[cnt] = c, head[a] = cnt++;
}
void bfs(int x)
{
for (int i = 0; i < N; i++)dis[i] = 0x3f;
for (int i = 0; i < N; i++)depth[i] = -1;
depth[0] = 0, depth[x] = 1;
dis[x] = 0;
queue<int> q;
q.push(x);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = head[u]; ~i; i = ne[i]) {
int j = e[i];
if (depth[j] == -1) {
depth[j] = depth[u] + 1;
dis[j] = dis[u] + w[i];
q.push(j);
fa[j][0] = u;
for (int i = 1; i <= 15; i++) {
fa[j][i] = fa[fa[j][i - 1]][i - 1];
}
}
}
}
}
int lca(int x, int y)
{
if (depth[x] < depth[y]) swap(x, y);
for (int i = 15; i >= 0; i--) {
if (depth[fa[x][i]] >= depth[y]) {
x = fa[x][i];
}
}
if (x == y) return x;
for (int i = 15; i >= 0; i--) {
if (fa[x][i] != fa[y][i]) {
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][0];
}
int main()
{
int n; cin >> n;
for (int i = 0; i < N; i++)head[i] = -1;
for (int i = 1; i < n; i++) {
int a, b; cin >> a >> b ;
add(a, b, 1), add(b, a, 1);
}
bfs(1);
int a, b; cin >> a >> b;
int res = dis[a] + dis[b] - 2 * dis[lca(a, b)];
if (res & 1)cout << "Yes" << endl;
else cout << "No" << endl;
return 0;
}
G题
思路:分类讨论,3种情况,每个人都在同一组,n+1张;每个组只有1个人,2张;正常情况3张地图
#include<iostream>
#include <stdlib.h>
#include <vector>
#include<stack>
#include <string>
#include<queue>
#include <set>
#include<stdbool.h>
#include <cmath>
using namespace std;
int main()
{
int T;
cin >> T;
while (T--)
{
int a, b;
cin >> a >> b;
if (b == 1)
{
cout << a + 1 << endl;
}
else if(a/b==1)
{
cout << 2 << endl;
}
else
{
cout << 3 << endl;
}
}
return 0;
}
I题
签到题
K题
思路:前面部分素数筛,后面过大的时候可以直接用密度特判去掉。