做题随笔2

gcd(n,n+1)=1

https://codeforces.com/problemset/problem/1521/B

s.find()

https://codeforces.com/problemset/problem/1845/C

做题反思:对于 \(s.find()\) 函数,前面为字符,后面为位置。
如果对一个字符串进行查找,查找完一个字符,要查找下一个字符串之前,需要对当前位置进行 \(+1\) 操作。

image

反悔贪心初识

https://codeforces.com/problemset/problem/1526/C2

思路:非负数药水全都喝掉,负数药水全都存到优先队列里,直到发现不够用了,检查是否能不喝亏损最大的药水来喝当前这瓶。
为什么不只存消耗最大的那一瓶呢?因为有可能前面喝了 \(-4,-5\) ,后面喝的两瓶都更优,所以要记所有的负数

按位贪心

https://codeforces.com/problemset/problem/484/A

思路:对于 \(l\) 来说,从低位开始贪心,若当前为 \(0\) ,设为 \(1\) ,看是否大于 \(r\),这样贪心可以使得 \(1\) 的数量变多的同时,使得当前数字尽量小

做题时的思路:从高位开始比较,从 \(l 和 r\) 第一个不同的位置开始,后面全是 \(1\)

哥德巴赫猜想

https://codeforces.com/problemset/problem/735/D

强猜想:对于任意一个大于2的偶数可以分为两个质数之和,
弱猜想:任意一个大于5的奇数可以分为三个质数之和

思路:利用结论,先处理质数,质数的代价一定为 \(1\),除2以外的偶数代价一定为 \(2\),再看大于 \(5\) 的奇数能不能分成一个 \(2\) 和一个质数,如果可以,代价为 \(2\),反之为 \(3\)

trick

https://codeforces.com/problemset/problem/1514/C

注意:几个数的乘积与 \(x\) 互质,当且仅当这几个数中的每一个数都与 \(x\)互质,并且乘积对 \(x\) 取模的余数也和 \(x\) 互质

思路:挑出序列中所有与 \(n\) 互质的数,模 \(n\) 后的结果 \(res\) 一定是和 \(n\) 互质的,因为 \(res\) 是模 \(n\) 得到的,所以一定小于 \(n\) ,如果这个数为 \(1\) ,那么答案就找到了,如果不为 \(1\),那么只要在序列中去除这个数就可以了

gcd(a,b)=gcd(a-b,b)

https://codeforces.com/problemset/problem/1458/A

这个性质不只是对两个数成立,多个数的时候也是成立的,所以原题中的 \(gcd(a_1+b_j,\cdots,a_n+b_j)\),就可以变成 \(gcd(a_1+b_j,\cdots,a_n-a_1)\),也就是后面的数全都减去第一个数,这样就可以预处理后面 \(n-1\) 个元素,遍历得到第一个元素就可以了

Code
点击查看代码
void solve()
{
    cin >> n >> m;
    vi a(n + 1), b(m + 1);
    int res = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (i != 1)
            res = gcd(res, abs(a[i] - a[1]));
    }
    for (int i = 1; i <= m; i++)
    {
        cin >> b[i];
        cout << gcd(a[1] + b[i], res) << ' ';
    }
}

反向图

思路:看似是双向奔赴,找出一个中间点,\(dist(1,i)=dist(1,k)+dist(k,i)\) ,如果直接进行计算,要对每一个点跑最短路,时间复杂度太大,所以建反图,代表另一只手的操作,这样的操作,就像是一个点从起点开始走,走到一定的地方可以把所有边方向全部反过来(只允许反一次)。所以对 点 \(i\) 和点 \(i+n\) 之间连一条边权为 \(0\) 的边,具体操作看代码

Code
点击查看代码
struct node
{
    int to, w;
};
vector<node> adj[M];
void solve()
{
    cin >> n >> m;
    while (m--)
    {
        int u, v, w;
        cin >> u >> v >> w;
        adj[u].push_back({v, w});
        adj[v + n].push_back({u + n, w});
    }
    for (int i = 1; i <= n; i++)
    {
        adj[i].pb({i + n, 0});
    }
    priority_queue<pii, vector<pii>, greater<pii>> p;
    vi res(2 * n + 7, -1);
    p.push({0, 1});
    res[1] = 0;
    while (p.size())
    {
        auto [d, i] = p.top();
        p.pop();
        if (d > res[i])
            continue;
        for (auto [j, w] : adj[i])
        {
            if (res[j] == -1 || res[j] > w + res[i])
            {
                res[j] = w + res[i];
                p.push({res[j], j});
            }
        }
    }
    for (int i = 2; i <= n; i++)
    {
        cout << res[i + n] << ' ';
    }
}
posted @ 2026-04-23 21:40  Lambda_L  阅读(12)  评论(0)    收藏  举报