每日一题-1
每日一题保持手感,主要做codeforces 1600 - 2200的题
难题有的时候一天做不了一道,补知识点
每次记录一周
# 1500A Going Home
Codeforces Round #707 1500A Going Home
tags: 暴力
这题真的是brain fuck
就是纯暴力,但是乍一看你会觉得暴力
然鹅只要一个和值出现超过四次(见官方题解),一定有解,所以上限是
点击展开
#include <bits/stdc++.h>
using namespace std;
//c++14 数字分位符
const int ms = 200'000 + 20;
unordered_map<int, set<int>> m;
int a[ms];
int main(int argc, char const *argv[])
{
int n;
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (size_t i = 1; i <= n; i++)
{
cin >> a[i];
}
for (size_t i = 1; i <= n; i++)
{
for (size_t j = i + 1; j <= n; j++)
{
int v = a[i] + a[j];
m[v].insert(i);
m[v].insert(j);
if (m[v].size() >= 4)
{
bool flag = false;
for (int x : m[v])
{
for (int y : m[v])
{
if (x == y)
continue;
for (int z : m[v])
{
if (z == x || z == y)
continue;
for (int w : m[v])
{
if (w == x || w == y || w == z)
continue;
if (a[x] + a[y] == a[w] + a[z])
{
cout << "YES\n";
cout << x << " " << y << " "
<< z << " " << w << "\n";
return 0;
}
}
}
}
}
}
}
}
cout << "NO\n";
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 1500B Two chandeliers
Codeforces Round #707 1500B Two chandeliers
tags: 二分,数论,中国剩余定理
官方题解写的太迷了……
有两个整数序列,序列初始时,每一个值是不同的。然后,将这两个序列将无限循环的重复下去,即
不难想到使用二分,对每个mid求有多少个点满足
直接求
假设初始序列中,
pos 需要满足
因为初始序列中的值是不重复的,所以在
点击展开
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int ms = 500000 + 5;
ll gcd(ll a, ll b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if (b == 0)
{
x = 1, y = 0;
return a;
}
ll gcd = exgcd(b, a % b, x, y);
ll tp = x;
x = y;
y = tp - a / b * y;
return gcd;
}
ll excrt(const vector<ll> &ai, const vector<ll> &mi)
{
ll ans = ai[0], M = mi[0]; //第一个式子的解
for (int i = 1; i < ai.size(); i++)
{
ll a = M, b = mi[i], c = (ai[i] - ans % b + b) % b, x, y;
ll gcd = exgcd(a, b, x, y);
if (c % gcd != 0)
{
return -1; //无解
}
ll bg = b / gcd;
x = c / gcd * x;
ans += x * M;
M = bg * M;
ans = (ans % M + M) % M;
}
return (ans % M + M) % M;
}
ll a[ms * 2], b[ms], cover[ms], cnt;
ll count(ll x)
{
return upper_bound(cover, cover + cnt, x) - cover;
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll n, m, k;
cin >> n >> m >> k;
ll lcm = n * m / gcd(n, m);
vector<ll> mi = {n, m};
ll ax;
for (int i = 0; i < n; i++)
{
cin >> ax;
a[ax] = i + 1;
}
for (int i = 0; i < m; i++)
{
cin >> b[i];
if (a[b[i]] > 0)
{
// 预处理出所有可能的pos
ll tmp = excrt({a[b[i]], i + 1}, mi);
if (tmp != -1)
{
if (tmp == 0)
tmp = lcm;
cover[cnt++] = tmp;
}
}
}
sort(cover, cover + cnt);
// 两个序列的对应情况以LCM(n,m)为周期循环
// 我们可以先算出进行了几个循环,然后处理剩下的
// 为了方便起见,我们使 1<=k<=n
ll base = lcm - count(lcm), res = 0;
res = (k - 1) / base * lcm;
k -= (k - 1) / base * base;
ll l = k, r = lcm + 1, mid, ans = 0;
while (l < r)
{
mid = (l + r) / 2;
ll rm = mid - count(mid);
if (rm < k)
{
l = mid + 1;
}
else
{
r = mid;
ans = mid;
}
}
cout << res + ans;
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 1499D The Number of Pairs
Educational Codeforces Round 106 (Rated for Div. 2) (opens new window)
tags:数论,dp
给定三个正整数
假设
由裴蜀定理可得,
那么对于
点击展开
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#ifdef DEBUG
const int ms = 100 + 5;
#else
const int ms = 2e7 + 5;
#endif
int minPrime[ms], numPrime[ms];
// 埃氏筛求最小素数
void eratosthenes()
{
int i = 2;
for (; i * i < ms; ++i)
{
if (minPrime[i] == 0)
{
minPrime[i] = i;
for (int j = i * i; j < ms; j += i)
{
if (minPrime[j] == 0)
minPrime[j] = i;
}
}
}
for (; i < ms; ++i)
if (minPrime[i] == 0)
minPrime[i] = i;
}
void dp()
{
for (int i = 2; i < ms; i++)
{
int j = i / minPrime[i];
numPrime[i] = numPrime[j];
if (minPrime[i] != minPrime[j])
{
numPrime[i]++;
}
}
}
int t, c, d, x;
int solve()
{
ll res = 0;
for (int i = 1; i * i <= x; ++i)
{
if (x % i != 0)
continue;
if ((x / i + d) % c == 0)
{
res += 1ll << numPrime[(x / i + d) / c];
}
if (i * i != x && (i + d) % c == 0)
{
res += 1ll << numPrime[(i + d) / c];
}
}
return res;
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> t;
eratosthenes();
dp();
while (t--)
{
cin >> c >> d >> x;
cout << solve() << "\n";
}
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 1497E1 Square-free division (easy version)
Codeforces Round #708 (Div. 2) (opens new window)
tags:数论,dp,贪心
给定一个n个正整数的序列,问最少可以划分成几个序列,使得序列中任意两个数的乘积不是某个正整数的平方
一个数a可以表示为质数的乘积
那么我们将a处理为
这题就变为判断一个序列里是否有数字出现两次
求a‘的思路和上一题类似
点击展开
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#ifdef DEBUG
const int ms = 100 + 5;
#else
const int ms = 1e7 + 5;
#endif
int minPrime[ms], numPrime[ms];
// 埃氏筛求最小素数
void eratosthenes()
{
int i = 2;
for (; i * i < ms; ++i)
{
if (minPrime[i] == 0)
{
minPrime[i] = i;
for (int j = i * i; j < ms; j += i)
{
if (minPrime[j] == 0)
minPrime[j] = i;
}
}
}
for (; i < ms; ++i)
if (minPrime[i] == 0)
minPrime[i] = i;
}
void dp()
{
numPrime[1] = 1;
for (int i = 2; i < ms; i++)
{
int j = i / minPrime[i];
if (numPrime[j] % minPrime[i] == 0)
numPrime[i] = numPrime[j] / minPrime[i];
else
numPrime[i] = numPrime[j] * minPrime[i];
}
}
int main(int argc, char const *argv[])
{
eratosthenes();
dp();
int t;
cin >> t;
while (t--)
{
int n, x, res = 0;
cin >> n >> x;
set<int> s;
while (n--)
{
cin >> x;
if (s.count(numPrime[x]))
{
s.clear();
res++;
}
s.insert(numPrime[x]);
}
if (!s.empty())
{
res++;
}
cout << res << "\n";
}
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75