• 序列


      题面:

      给定一个序列,对于一个区间,其价值为不在区间内的数之间的两两最大公约数的最大值,请求出所有长度<=n-2的区间的价值之和。

      代码:

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <vector>
    #define maxn 200005
    using namespace std;
    struct node
    {
        int l, r, mx, set;
        long long s;
    } tree[maxn * 4];
    void upd(int rt, int x)
    {
        tree[rt].mx = tree[rt].set = x;
        tree[rt].s = 1LL * (tree[rt].r - tree[rt].l + 1) * x;
    }
    void pushup(int rt)
    {
        tree[rt].mx = max(tree[rt << 1].mx, tree[rt << 1 | 1].mx);
        tree[rt].s = tree[rt << 1].s + tree[rt << 1 | 1].s;
    }
    void pushdown(int rt)
    {
        if (tree[rt].set != -1)
        {
            upd(rt << 1, tree[rt].set);
            upd(rt << 1 | 1, tree[rt].set);
            tree[rt].set = -1;
        }
    }
    void build(int rt, int l, int r)
    {
        tree[rt].l = l, tree[rt].r = r;
        tree[rt].set = -1;
        if (l == r)
        {
            tree[rt].mx = tree[rt].s = l - 1;
            return;
        }
        build(rt << 1, l, l + r >> 1);
        build(rt << 1 | 1, (l + r >> 1) + 1, r);
        pushup(rt);
    }
    void update(int rt, int l, int r, int x)
    {
        if (tree[rt].r < l || r < tree[rt].l)
            return;
        if (l <= tree[rt].l && tree[rt].r <= r)
        {
            upd(rt, x);
            return;
        }
        pushdown(rt);
        update(rt << 1, l, r, x);
        update(rt << 1 | 1, l, r, x);
        pushup(rt);
    }
    long long sum(int rt, int l, int r)
    {
        if (tree[rt].r < l || r < tree[rt].l)
            return 0;
        if (l <= tree[rt].l && tree[rt].r <= r)
            return tree[rt].s;
        pushdown(rt);
        return sum(rt << 1, l, r) + sum(rt << 1 | 1, l, r);
    }
    int search(int rt, int x)
    {
        if (tree[rt].mx < x)
            return -1;
        if (tree[rt].l == tree[rt].r)
            return tree[rt].l;
        pushdown(rt);
        return tree[rt << 1].mx >= x ? search(rt << 1, x) : search(rt << 1 | 1, x);
    }
    int n;
    long long solve(int l, int r, int h)
    {
        int pos = search(1, h);
        if (pos == -1)
            pos = n + 1;
        if (pos <= l)
            return 0;
        r = min(r, pos - 1);
        long long ans = 1LL * (r - l + 1) * h - sum(1, l, r);
        update(1, l, r, h);
        return ans;
    }
    vector <int> G[maxn];
    int read()
    {
        char ch = getchar();
        int cnt = 0;
        while (ch < '0' || '9' < ch)
            ch = getchar();
        while ('0' <= ch && ch <= '9')
        {
            cnt = cnt * 10 + ch - '0';
            ch = getchar();
        }
        return cnt;
    }
    int main()
    {
        freopen("sequence.in", "r", stdin);
        freopen("sequence.out", "w", stdout);
        n = read();
        int mx = 0;
        for (int i = 1; i <= n; ++ i)
        {
            int a = read();
            mx = max(mx, a);
            for (int j = 1; j * j <= a; ++ j)
                if (a % j == 0)
                {
                    G[j].push_back(i);
                    if (j != a / j)
                        G[a / j].push_back(i);
                }
        }
        build(1, 1, n);
        long long ans = 0;
        for (int i = mx; i; -- i)
            if (G[i].size() >= 2)
            {
                sort(G[i].begin(), G[i].end());
                int l = G[i][0], r = G[i][G[i].size() - 1], a = G[i][1], b = G[i][G[i].size() - 2];
                long long cnt = solve(1, l, b - 1) + solve(l + 1, a, r - 1) + (a < n ? solve(a + 1, n, n) : 0);
                ans += cnt * i;
            }
        cout << ans << endl;
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    java中4种修饰符访问权限的区别
    Java中List的排序方法
    Hibernate事务
    @Component、@Service、@Constroller
    MySQL查看一个表的创建文本以及删除表某列的索引
    深入Session2
    Tomcat容器的Session管理
    深入Session
    使用spring mvc或者resteasy构建restful服务
    Spring MVC学习回顾
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/11103941.html
Copyright © 2020-2023  润新知