C.Hossamand Trainees
欧拉筛,预处理先筛出质数,分解质因数对于出现两次及以上的输出yes
我们需要筛出根号(1e9)以内的所有质数,根据质数定理,大约有4e^3个质数,
时间复杂度分析:le5*4e3=4e8
- #include
- #pragma GCC optimize(2)
- #pragma GCC optimize(3)
- #pragma GCC optimize(fast)
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #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
- #pragma GCC optimize(2)
- #pragma GCC optimize(3)
- #pragma GCC optimize(fast)
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #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
- #pragma GCC optimize(2)
- #pragma GCC optimize(3)
- #pragma GCC optimize(fast)
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #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
- 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
- #pragma GCC optimize(2)
- #pragma GCC optimize(3)
- #pragma GCC optimize(fast)
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #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<
//枚举所有状态 - 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
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #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();
- }
- }