有人能帮帮我吗?我真的心态崩了
查看原帖
有人能帮帮我吗?我真的心态崩了
342798
Desert_Lycoris楼主2020/8/25 21:05
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int g[N], sum[N], dep[N], fa[N], id[N], son[N], wp[N << 2], top[N], w[N], edge[N], nxt[N];
int tree[N << 2], put[N << 2], pre;
int n, m, r, p, cnt = 0, x, y, t, k, num = 0;
inline void add(int from, int to)
{
    edge[++cnt] = to;
    nxt[cnt] = g[from];
    g[from] = cnt;
}
inline void findson(int x)
{
    sum[x] = 1;
    for(int i = g[x]; i; i = nxt[i])
    {
        int now = edge[i];
        if(now == fa[x]){continue;}
        if(fa[now] == 0)
        {
            fa[now] = x;
            dep[now] = dep[x] + 1;
            findson(now);
            sum[x] += sum[now];
            if(son[x] == 0 || sum[now] > sum[son[x]]){son[x] = now;}
        }
    }
}
inline void findtop(int x)
{
    id[x] = ++num;
    wp[num] = w[x];
    if(!son[x]){return;}
    top[son[x]] = top[x];
    findtop(son[x]);
    for(int i = g[x]; i; i = nxt[i])
    {
        int now = edge[i];
        if(now != fa[now] && now != son[x])
        {
            top[now] = now;
            findtop(now);
        }
    }
}
/*↓↓↓————————线段树————————↓↓↓*/
inline void build(int rt, int l, int r)
{
    if(l == r)
    {
        tree[rt] = wp[l];
        if(tree[rt] > p){tree[rt] %= p;}
        return;
    }
    int mid = (l + r) >> 1;
    build(rt << 1, l, mid);
    build(rt << 1 | 1, mid + 1, r);
    tree[rt] = (tree[rt << 1] + tree[rt << 1 | 1]) % p;
}
inline void down(int x, int l, int r)
{
    int mid = (l + r) >> 1;
    int len1 = (mid - l + 1) % p;
    int len2 = (r - mid) % p;
    put[x << 1] += put[x];
    put[x << 1] %= p;
    put[x << 1 | 1] += put[x];
    put[x << 1 | 1] %= p;
    tree[x << 1] += put[x] * len1;
    tree[x << 1] %= p;
    tree[x << 1 | 1] += put[x] * len2;
    tree[x << 1 | 1] %= p;
    put[x] = 0;
}
inline void change(int rt, int l, int r, int x, int y, int d)
{
    if(y < l || r < x){return;}
    if(x <= l && r <= y)
    {
        int len = (r - l + 1) % p;
        int e = d % p;
        tree[rt] += e * len;
        tree[rt] %= p;
        put[rt] += d;
        return;
    }
    if(put[rt]){down(rt, l, r);}/*如果put[x] = 0,传下去也没有意义,相当于没传,剪枝*/
    int mid = (l + r) >> 1;
    if(x <= mid){change(rt << 1, l, mid, x, y, d);}
    if(y > mid){change(rt << 1 | 1, mid + 1, r, x, y, d);}
    tree[rt] = (tree[rt << 1] + tree[rt << 1 | 1]) % p;
}
inline void query(int rt, int l, int r, int x, int y)
{
    if(y < l || r < x){return;}
    if(x <= l && r <= y)
    {
        pre += tree[rt];
        pre %= p;
        return;
    }
    if(put[rt]){down(rt, l, r);}/*如果put[x] = 0,传下去也没有意义,相当于没传,剪枝*/
    int mid = (l + r) >> 1;
    if(x <= mid){query(rt << 1, l, mid, x, y);}
    if(y > mid){query(rt << 1 | 1, mid + 1, r, x, y);}
    tree[rt] = (tree[rt << 1] + tree[rt << 1 | 1]) % p;
}
/*↑↑↑————————线段树————————↑↑↑*/
inline void conchain(int flag, int x, int y, int d)
{
    int ans = 0;
    while(top[x] != top[y])
    {
        if(dep[top[x]] < dep[top[y]]){swap(x, y);}
        if(flag == 1)
        {
            change(1, 1, n, id[top[x]], id[x], d);
        }
        if(flag == 2)
        {
            pre = 0;
            query(1, 1, n, id[top[x]], id[x]);
            ans += pre;
            ans %= p;
        }
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]){swap(x, y);}
    if(flag == 1)
    {
        change(1, 1, n, id[y], id[x], d);
    }
    if(flag == 2)
    {
        pre = 0;
        query(1, 1, n, id[y], id[x]);
        ans += pre;
        ans %= p;
        cout << ans << endl;
    }
}
inline void contree(int flag, int x, int d)
{
    if(flag == 3)
    {
        change(1, 1, n, id[x], id[x] + sum[x] - 1, d);
    }
    if(flag == 4)
    {
        pre = 0;
        query(1, 1, n, id[x], id[x] + sum[x] - 1);
        cout << pre <<endl;
    }
}
int main()
{
    cin >> n >> m >> r >> p;
    for(int i = 1; i <= n; i++)
    {
        cin >> w[i];
    }
    for(int i = 1; i < n; i++)
    {
        cin >> x >> y;
        add(x, y);
        add(y, x);
    }
    fa[r] = r;
    top[r] = r;
    findson(r);
    findtop(r);
    build(1, 1, n);
    for(int i = 1; i <= m; i++)
    {
        cin >> t;
        if(t == 1)
        {
            cin >> x >> y >> k;
            conchain(t, x, y, k);
        }
        if(t == 2)
        {
            cin >> x >> y;
            conchain(t, x, y, k);
        }
        if(t == 3)
        {
            cin >> x >> k;
            contree(t, x, k);
        }
        if(t == 4)
        {
            cin >> x;
            contree(t, x, k);
        }
    }
}

求助求助,看我的提交记录您就能明白我的苦楚……已经调了一天了,依然是T/MLE

2020/8/25 21:05
加载中...