首页 > 其他分享 >[题解]CF154B Colliders

[题解]CF154B Colliders

时间:2024-06-23 13:14:03浏览次数:16  
标签:CF154B int 题解 更新 vis 质因数 Colliders

思路

首先我们将两种操作分开讨论:

Part 1 加入操作

那么,我们可以用一个数组 \(vis_i = 0/1\) 表示 \(i\) 是 关闭/开启 状态,\(p_i\) 表示因数有 \(i\) 的数。

如果 $vis_x =1 $,说明此机器在之前已经启动过了,输出 Success

然后,对 \(x\) 分解质因数,将质因数全部塞进一个集合 \(a\) 里面。

如果对于任意一个 \(i \in |a|\),\(p_i = 0\) 那么表示启动 \(x\) 是合法的,然后更新 \(p_{a_i}\) 为 \(x\),输出 Success。(注意还需要更新 \(vis_x\))

否则,就随便找到一个 \(p_{a_i} \neq 0\),即可。

Part 2 删除操作

与加入操作同理。

如果 \(vis_x = 0\),说明此机器已经处于关闭状态,输出 Already off

然后还是分解质因数,更新 \(p_i\) 的值即可。(注意还需要更新 \(vis_i\) 的值)

时间复杂度为 \(\Theta(n \sqrt n)\)。

Code

#include <bits/stdc++.h>  
#define re register  
  
using namespace std;  
  
const int N = 1e5 + 10;  
int n,q;  
int p[N];  
bool vis[N];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
int main(){  
    n = read();  
    q = read();  
    while (q--){  
        char op[10];  
        int x;  
        scanf("%s",op);  
        x = read();  
        if (op[0] == '+'){  
            if (vis[x]) puts("Already on");  
            else{  
                int ans = 0,val = x;  
                bool ok = true;  
                vector<int> v;  
                for (re int i = 2;i * i <= x && ok;i++){  
                    if (x % i == 0){  
                        if (p[i]){  
                            ok = false;  
                            if (p[i]) ans = p[i];  
                            else ans = p[x / i];  
                        }  
                        else{  
                            v.push_back(i);  
                            while (x % i == 0) x /= i;  
                        }  
                    }  
                }  
                if (x != 1){  
                    if (p[x]){  
                        ok = false;  
                        ans = p[x];  
                    }  
                    else v.push_back(x);  
                }  
                if (ok){  
                    vis[val] = true;  
                    for (auto num:v) p[num] = val;  
                    puts("Success");  
                }  
                else printf("Conflict with %d\n",ans);  
            }  
        }  
        else{  
            if (!vis[x]) puts("Already off");  
            else{  
                vis[x] = false;  
                for (re int i = 2;i * i <= x;i++){  
                    if (x % i == 0){  
                        p[i] = 0;  
                        while (x % i == 0) x /= i;  
                    }  
                }  
                if (x != 1) p[x] = 0;  
                puts("Success");  
            }  
        }  
    }  
    return 0;  
}  

标签:CF154B,int,题解,更新,vis,质因数,Colliders
From: https://www.cnblogs.com/WaterSun/p/18263297

相关文章

  • [题解]AT_dp_w Intervals
    思路首先考虑较为普通的DP。定义\(dp_{i,j}\)表示在前\(i\)个位置中,最后一个1在\(j\)的最大分数,显然有:\[dp_{i,j}=\left\{\begin{matrix}\max_{k=1}^{i-1}\{dp_{i-1,k}\}+\sum_{l_k\leqj\wedger_k=i}{a_k}&(i=j)\\dp_{i-1,j}+\sum......
  • [题解]AT_arc138_a [ARC138A] Larger Score
    思路不难发现:对于每一个\(i(1\leqi\leqk)\),如果能在\((k+1)\simn\)中找到任何一个\(j\),满足\(a_j>a_i\)就算满足条件。进一步思考,为了使操作数最小,对于每一个\(1(1\leqi\leqk)\),都找一个在\((k+1)\simn\)中第一个大于\(a_i\)的数,便于它交换。那么......
  • [题解]AT_arc116_d [ARC116D] I Wanna Win The Game
    思路因为题目与二进制有关,考虑往二进制的方向思考。定义\(dp_{i,j}\)表示在所有的\(n\)个数中,当前在决策对于每一个数在二进制表示下的第\(i\)位是\(0\)还是\(1\),且和为\(j\)的方案数。因为异或需要满足对于所有\(a_i\)表示为二进制后每一位\(1\)的个数均为偶数......
  • [题解]AT_arc116_b [ARC116B] Products of Min-Max
    思路我们容易可以得到一个朴素的做法,首先对\(a\)数组排序,然后枚举最大值和最小值\(a_i,a_j\),那么对于中间的元素都有选与不选两种情况,得到答案:\[\sum_{i=1}^{n}(a_i\timesa_i+(\sum_{j=i+1}^{n}a_i\timesa_j\times2^{j-i-1}))\]然后对这个式子......
  • [题解]AT_arc113_c [ARC113C] String Invasion
    题意给定一个字符串\(S\),你可以选择一个\(i(1\leqi\leq|S|)\),如果\(s_i=s_{i+1}\neqs_{i+2}\),就将\(s_{i+2}\)设为\(s_i\)。问:最多能操作几次。思路我们可以用一个后缀和\(s_{i,j}\)维护\(S_i\simS_n\)中与\(j\)不同的数量。然后,我们可以发现一......
  • [题解]AT_arc079_c [ARC079E] Decrease (Judge ver
    思路首先,对于每一次操作,我们可以先找到最大值,然后对其操作。这样,我们可以得到单次操作时间复杂度\(\Theta(n)\)的代码,因为\(n\)很小,所以这道题时间复杂度的瓶颈在于操作的数量。那么,我们想到每一次找到最大值时,直接将其减到小于\(n\)。但是这样可能有一种问题,就是最大值......
  • [题解]AT_agc054_b [AGC054B] Greedy Division
    思路首先不难发现一个规律,当\(sum\)为奇数时不可能有解。定义\(dp_{i,j,k,0/1}\)表示A在前\(i\)个数中选出和为\(j\)的\(k\)个数,且第\(i\)个不选/选的方案数。那么,我们只需要对于第\(i\)个数的状态分类讨论就能得到状态转移方程:不选\(i\),\(dp_{i,j,k,0}=......
  • [题解]AT_abc350_g [ABC350G] Mediator
    思路有加边操作,一眼LCT。问题在于处理询问操作。首先,判断联通。如果\(x,y\)不在同一个联通块内,则一定没有答案。其次,求出\(x,y\)之间节点的数量\(num\)(包括\(x,y\))。如果\(num=3\)说明\(x,y\)之间有一个共同的节点;如果\(num=2\)说明\(x,y\)直接连接;如果\(n......
  • [题解]AT_abc343_g [ABC343G] Compress Strings
    思路首先假设有两个串\(a,b\),如果\(b\)是\(a\)的子串,且\(a\neqb\)则不需要考虑\(b\);如果\(a=b\),则如需要保留一个\(a\)。做完上述操作后,显然最终的答案是由这些串按照一定顺序拼接起来,再删掉重叠部分。例如:abbcc与ccdde拼接为abbccccdde,发现cc是重复的,所以......
  • [题解]AT_abc342_f [ABC342F] Black Jack
    思路发现自己与庄家的操作是完全独立的,所以考虑分别计算它们。首先考虑自己的情况,定义\(dp_i\)表示掷出骰子的和为\(i\)获胜的概率,并记\(f(i)\)表示\(x=i\)时就不掷的获胜概率。对于每一步我们要么掷骰子(并且掷出的值等概率的在\(1\simD\)中),要么直接结束。两种情......