C.Hossamand Trainees
欧拉筛,预处理先筛出质数,分解质因数对于出现两次及以上的输出yes
我们需要筛出根号(1e9)以内的所有质数,根据质数定理,大约有4e^3个质数,
时间复杂度分析:le5*4e3=4e8
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#define ms(x,y) memset(x,y,sizeof x)
#define int long long
const int maxn = 2e5 + 10, INF = 0x3f3f3f3f;
using namespace std;
int a[maxn];
int cnt = 0;
int st[1000060];
int p[1000060];
void init() {
for (int i = 2; i < 40000; i++) {
if (!st[i])
p[cnt++] = i;
for (int j = 0; p[j] * i < 40000; j++) {
st[p[j] * i] = true;
if (i % p[j] == 0)
break;
}
}
}
void solve() {
int n;
cin >> n;
map<int, int>mp;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
int num = a[i];
for (int j = 0; p[j] * p[j] <= num; j++) {
int p1 = p[j];
if (num % p1 == 0) {
while (num % p1 == 0) {
num /= p1;
}
mp[p1]++;
if (mp[p1] > 1) {
cout << "YES" << '\n';
return;
}
}
}
if (num >1)mp[num]++;
if (mp[num] > 1) {
cout << "YES" << '\n';
return;
}
}
cout << "NO" << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
init();
int t;
cin >> t;
while (t--) {
solve();
}
}
B.Hossamand Friends
思路:双指针,用一个数组记录右指针可取的最大左边界
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#define ms(x,y) memset(x,y,sizeof x)
#define int long long
const int maxn=2e5+10,INF = 0x3f3f3f3f ;
using namespace std;
int a[maxn];
void solve(){
int n, m;
cin >> n >> m;
vector<int>l(n+1); //左边界
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
if (x < y)swap(x, y);
l[x] = max(l[x], y);
}
int sum = 0;
int r = 1;
for (int i = 1; i <=n; i++) {
while (r + 1 <= n && l[r + 1] < i) ++r;
sum += (r-i + 1);
}
cout << sum << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
solve();
}
}
G.Chevonne’s Necklace
思路:采用dp,01背包,可取大小视为体积,
因为选择移除的珍珠(p1,p2...)可取大小(ap1+ap2...)的和<=n,至少存在一个下一次选中的珍珠与上一次选中珍珠的距离dis>cpi,否则矛盾
故移除顺序不影响方案数,最终选中的珍珠是从珍珠1开始的连续编号.
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#define ms(x,y) memset(x,y,sizeof x)
#define int long long
const int maxn=2e5+10,INF = 0x3f3f3f3f ;
const int mod = 998244353;
using namespace std;
int a[maxn];
int dp[maxn]; //记录方案数,dp[i]表示当取i个珍珠时的最大方案数
bool vis[maxn];
void solve(){
int n;
cin >> n;
for (int i = 0; i<n; i++) {
cin >> a[i];
}
dp[0] = 1;
vis[0] = 1;
for (int i = 0; i < n; i++) { //枚举珍珠编号
if (a[i] >= 1) {
for (int j = n; j >= a[i]; j--) { //01
vis[j] |= vis[j-a[i]]; //记录珍珠状态
dp[j] = (dp[j] + dp[j - a[i]]) % mod;
}
}
}
int sum = n;
while (!vis[sum]) {
sum--;
}
cout << sum << ' ' << dp[sum]%mod << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
solve();
}
G - ORXOR
思路:状态压缩,枚举所有状态,对标记点集合异或,集合元素或运算
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define ms(x,y) memset(x,y,sizeof x)
#define int long long
const int maxn=2e5+10,INF = 1e18 ;
using namespace std;
int a[maxn];
void solve(){
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int Min = INF;
for (int i = 0; i <(1<<n); i++) { //枚举所有状态
int t1=0, t2=0;
for (int j = 0; j <= n; j++) { //枚举所有元素,多一次进行最终合并
if (j < n) t1 |= a[j]; //|00为0
if (j == n || i & ((1) << j)) {
t2 ^= t1;
t1 = 0;
}
}
Min = min(Min, t2);
}
cout << Min << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
int t;
solve();
}
C:Hamiltonian Wall
题意:能否一笔把B格子全部画完(一笔画完)
思路:使用dp,记录最后一个B位置和第一个B位置,若最后一列的B能否由开头转移过来,则YES,否则NO
转移的策略有三种,
1.一列有两个B,转移位置与上一列B转移位置相异;
2.一列有一个B,位置与上一列(一个B)位置相同
3.一列有一个B,位置与上一列(两个B)转移位置相同
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(fast)
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define ms(x,y) memset(x,y,sizeof x)
#define int long long
const int maxn=2e5+10,INF = 1e18 ;
using namespace std;
int a[3][maxn];
int f[maxn][3];
void solve(){
int n;
cin >> n;
for (int i = 1;i<=2; i++) {
for (int j = 1; j <= n; j++) {
char c;
cin >> c;
if (c == 'B')
a[i][j] = 1;
else
a[i][j] = 0;
}
}
int Min = n+1, Max = -1, flag = 0;
for (int i = 1; i <= n; i++) {
f[i][1] = 0;
f[i][2] = 0;
if (a[1][i] || a[2][i]) {
Min = min(Min, i);
Max = max(Max, i);
flag = 1;
}
}
if (!flag) {
cout << "YES" << '\n';
return;
}
f[Min][1] = (a[1][Min] == 1);
f[Min][2] = (a[2][Min] == 1);
for (int i = Min+1; i <= Max; i++) {
if (a[1][i] == 1 && a[2][i] == 1) {
f[i][1] = f[i - 1][2];
f[i][2] = f[i - 1][1];
}
if (a[1][i] == 1 && a[2][i] == 0) {
f[i][1] = f[i - 1][1];
}
if (a[1][i] == 0 && a[2][i] == 1) {
f[i][2] = f[i - 1][2];
}
}
if (f[Max][1] || f[Max][2]) {
cout << "YES" << '\n';
}
else {
cout << "NO" << '\n';
}
}
signed main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
solve();
}
}