• 省选测试44


    A island (Unaccepted)

    题目大意 :

    Code

    Show Code

    B river

    题目大意 : 第i天出发要花费a[i]到达下一个地点,可以等几天再出发,问走n个地点最少花费多少天

    • 先算出从某天出发到达下一个地点最少花费多少天,肯定就是max(a[i],a[i+1]+1,a[i+2]+2,...),

    • 如果复制一遍放后面,给每个加上i,然后区间求max,再减去i就是答案(滑动窗口那样做)

    • 然后算出从每天出发,都按最优策略走,会到那一天,建出图来会发现是一个内向基环树森林,然后从0开始走,找环就行

    Code

    Show Code
    #include <cstdio>
    
    using namespace std;
    const int N = 2e6 + 5;
    
    int read(int x = 0, int f = 1, char c = getchar()) {
        for (; (c < '0' || c > '9'); c = getchar()) if (c == '-') f = -1;
        for (;!(c < '0' || c > '9'); c = getchar()) x = x * 10 + c - '0';
        return x * f;
    }
    
    bool v[N];
    long long ans, sum;
    int m, n, a[N], q[N], b[N], t[N], stk[N], tp;
    
    int main() {
        freopen("river.in", "r", stdin);
        freopen("river.out", "w", stdout);
        m = read(); n = read();
        for (int i = 0; i < n; ++i)
            a[i] = a[i+n] = read();
        int l = 1, r = 0;
        for (int i = 0; i < n + n; ++i) {
            a[i] += i;
            while (l <= r && q[l] < i - n) l++;
            if (i >= n) {
                b[i-n] = a[q[l]] - (i - n);
                t[i-n] = a[q[l]] % n;
            }
            while (l <= r && a[q[r]] >= a[i]) r--;
            q[++r] = i;
        }
        for (int x = 0; !v[x]; x = t[x])
            v[x] = 1, stk[++tp] = x, sum += b[x];
        int st = t[stk[tp]];
        for (int i = 1; i <= tp && m; ++i, --m) {
            int x = stk[i];
            ans += b[x];
            if (x != st) continue;
            ans -= b[x];
            ans += m / (tp - i + 1) * (sum - ans);
            m %= (tp - i + 1); st = x; break;
        }
        for (int x = st; m--; x = t[x])
            ans += b[x];
        printf("%lld
    ", ans);
        return 0;
    }
    

    C cac

    题目大意 : 给一个仙人掌图,每次把两点间所有简单路径上的点都加一个值,每次每个点只加一遍,询问一个点的权值

    • 建出圆方树,修改的时候给路径上的方点都加上,然后原点的权值就是父亲的方点的值,发现lca的地方会少算,新开个数组加上就好

    Code

    Show Code
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    const int N = 8e5 + 5, M = 998244353;
    
    int read(int x = 0, int f = 1, char c = getchar()) {
        for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;
        for (; c >='0' && c <='9'; c = getchar()) x = x * 10 + c - '0';
        return x * f;
    }
    
    struct Edge {
        int n, t;
    }e[N];
    int h[N/2], edc;
    
    void Add(int x, int y) {
        e[++edc] = (Edge) {h[x], y}; h[x] = edc;
        e[++edc] = (Edge) {h[y], x}; h[y] = edc;
    }
    
    vector<int> to[N];
    int n, m, q, dfn[N], dfc, low[N], stk[N], top, cnt;
    int sz[N], son[N], tp[N], dep[N], fa[N], t[N], a[N];
    
    void Tarjan(int x) {
        dfn[x] = low[x] = ++dfc; stk[++top] = x;
        for (int i = h[x], y; i; i = e[i].n) {
            if (!dfn[y=e[i].t]) {
                Tarjan(y); low[x] = min(low[x], low[y]);
                if (low[y] != dfn[x]) continue; ++cnt;
                while (1) {
                    int z = stk[top--];
                    to[z].push_back(cnt);
                    to[cnt].push_back(z);
                    if (z == y) break;
                }
                to[x].push_back(cnt);
                to[cnt].push_back(x);
            }
            else low[x] = min(low[x], dfn[y]);
        }
    }
    
    void Dfs(int x) {
        dep[x] = dep[fa[x]] + 1; sz[x] = 1;
        for (int i = 0, y; i < to[x].size(); ++i) {
            if ((y = to[x][i]) == fa[x]) continue;
            fa[y] = x; Dfs(y); sz[x] += sz[y];
            if (sz[son[x]] < sz[y]) son[x] = y;
        }
    }
    
    void Dfs(int x, int top) {
        tp[x] = top; dfn[x] = ++dfc;
        if (son[x]) Dfs(son[x], top);
        for (int i = 0, y; i < to[x].size(); ++i)
            if ((y = to[x][i]) != fa[x] && y != son[x]) Dfs(y, y);
    }
    
    void Add(int l, int r, int w) {
        for (; l <= cnt; l += l & -l) 
            if ((t[l] += w) >= M) t[l] -= M;
        for (r++; r <= cnt; r += r & -r) 
            if ((t[r] -= w) <  0) t[r] += M;
    }
    
    int Ask(int x, int ans = 0) {
        for (; x; x -= x & -x)
            if ((ans += t[x]) >= M) ans -= M;
        return ans;
    }
    
    int main() {
        freopen("cac.in", "r", stdin);
        freopen("cac.out", "w", stdout);
        cnt = n = read(); m = read(); q = read();
        while (m--) Add(read(), read());
        Tarjan(1); dfc = 0; Dfs(1); Dfs(1, 1);
        while (q--) {
            int od = read(), x = read();
            if (od) printf("%d
    ", (a[x] + Ask(dfn[fa[x]])) % M);
            else {
                int y = read(), w = read();
                while (tp[x] != tp[y]) {
                    if (dep[tp[x]] < dep[tp[y]]) swap(x, y);
                    Add(dfn[tp[x]], dfn[x], w); x = fa[tp[x]];
                }
                if (dfn[x] > dfn[y]) swap(x, y);
                Add(dfn[x], dfn[y], w);
                x > n ? ((a[fa[x]] += w) >= M ? a[fa[x]] -= M : 0) : ((a[x] += w) >= M ? a[x] -= M : 0);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    git修改远程仓库地址
    Result Maps collection already contains value for com.miniprogram.meirong.user.dao.UserMapper.BaseResultMap
    查看微信小程序的appID和secret
    Springboot配置fastjson开发
    本地仓库上传码云
    总结分析Java常见的四种引用
    equals和hashcode 和 ==方法说明
    关于Class.forName(className).newInstance()介绍
    Java枚举
    抽象工厂模式-与-工厂方法模式区别
  • 原文地址:https://www.cnblogs.com/shawk/p/14564558.html
Copyright © 2020-2023  润新知