省选测试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\n", 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\n", (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;
}
posted @ 2021-03-22 21:39  Shawk  阅读(42)  评论(0编辑  收藏  举报