9MLE 2, 10RE,求大佬指点
查看原帖
9MLE 2, 10RE,求大佬指点
494301
ch2535053498楼主2021/4/17 22:21
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;
//const int N = 100;


int p;
int to[N], nex[N], head[N];
int dfs[N], fa[N], sz[N], dep[N], nd[N], son[N], top[N], d[N];

int idx;//边的序号
void add(int a, int b)//增加一条a到b的有向边
{
    to[++idx] = b;//边的终点
    nex[idx] = head[a];//同一起点的上一条边
    head[a] = idx;//以a为起点的最后一条边
}

int cnt = 0;
void dfs1(int u,int father, int depth)
{
    dep[u] = depth;
    fa[u] = father;
    sz[u] = 1;
    for(int i = head[u]; i!= -1; i = nex[i])
    {
        int t = to[i];
        if(t == fa[u]) continue;
        dfs1(t, u, depth+1);
        sz[u] += sz[t];
        if(sz[son[u]] < sz[t]) son[u] = t;
    }
}

void dfs2(int u, int tt)//节点u的顶部节点为tt
{
    dfs[u] = ++cnt;
    top[u] = tt;
    nd[cnt] = d[u];//dfs序为cnt的值
    if(!son[u]) return;//没有重孩子
    dfs2(son[u], tt);//先搜索重孩子
    for(int i = head[u]; i != -1; i = nex[i])
    {
        int t = to[i];
        if(t == son[u] || t == fa[u]) continue;
        dfs2(t, t);//轻链开端的顶部就是他自己
    }
}

struct node//节点rt所包含的信息
{
    int l,r,lz,v;
}tree[N<<2];

void push_up(int rt)
{
    tree[rt].v = (tree[rt<<1].v + tree[rt<<1|1].v)%p;
}

void push_down(int rt)
{
    if(tree[rt].lz)
    {
        tree[rt<<1].lz += tree[rt].lz;
        tree[rt<<1|1].lz += tree[rt].lz;
        tree[rt<<1].v = tree[rt<<1].v + (tree[rt<<1].r - tree[rt<<1].l+1)*tree[rt].lz;
        tree[rt<<1|1].v = tree[rt<<1|1].v + (tree[rt<<1|1].r - tree[rt<<1|1].l+1)*tree[rt].lz;
        tree[rt].lz = 0;
    }
}

void bulid(int rt, int l, int r)
{
    tree[rt] = {l, r};
    if(l == r)
    {
        tree[rt].v = nd[l];
        return ;
    }
    int mid = (l + r)>>1;
    bulid(rt<<1, l, mid);
    bulid(rt<<1|1, mid+1, r);
    push_up(rt);
}

void modify(int rt, int l, int r, int k)
{
    if(l <= tree[rt].l && tree[rt].r <= r)
    {
        tree[rt].lz += k;
        tree[rt].v = (tree[rt]. v +k * (tree[rt].r - tree[rt].l + 1))%p;
        return;
    }
    push_down(rt);
    int mid = (tree[rt].l+tree[rt].r)>>1;
    if(l <= mid) modify(rt<<1, l, r, k);
    if(mid + 1 <= r) modify(rt<<1|1, l ,r ,k);
    push_up(rt);
}

int query(int rt, int l, int r)
{
    if(l <= tree[rt].l && tree[rt].r <= r)
    {
        return tree[rt].v%p;
    }
    push_down(rt);
    int ans = 0;
    int mid = (tree[rt].l + tree[rt].r) >> 1;
    if(l <= mid) ans = (ans + query(rt<<1, l, r))%p;
    if(mid + 1 <= r) ans =( ans +  query(rt<<1|1, l, r))%p;
    return ans%p;
}

void modify_tree(int u, int k)
{
    modify(1, dfs[u], dfs[u] + sz[u] - 1, k);
}

int query_tree(int u)
{
    return query(1, dfs[u], dfs[u] + sz[u] - 1)%p;
}

void modify_path(int u, int v, int k)
{
    while(top[u] != top[v])
    {
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        modify(1, dfs[top[u]], dfs[u], k);
        u = fa[top[u]];
    }
    if(dep[u] < dep[v]) swap(u , v);
    modify(1, dfs[v], dfs[u], k);
}

int query_path(int u, int v)
{
    int ans = 0;
    while(top[u] != top[v])
    {
        if(dep[top[u]] < dep[top[v]]) swap(u, v);
        ans =  (ans + query(1, dfs[top[u]], dfs[u]))%p;
        u = fa[top[u]];
    }
    if(dep[u] < dep[v]) swap(u, v);
    ans = (ans + query(1, dfs[v], dfs[u]))%p;
    return ans;
}

int main()
{
    memset(head, -1, sizeof(head));
    int n,m,root;
    cin>>n>>m>>root>>p;
    for(int i = 1; i <= n; ++i)
    {
        cin>>d[i];
    }
    for(int i = 1; i <= n-1; ++i)
    {
        int a,b;
        cin>>a>>b;
        add(a, b);
        add(b, a);
    }
    dfs1(root, -1, 1);
    dfs2(root, root);
    bulid(1, 1, n);
    for(int i = 1; i <= m; ++i)
    {
        int op,x,y,z;;
        cin>>op;
        if(op == 1)
        {
            cin>>x>>y>>z;
            modify_path(x, y, z);
        }
        else if(op == 2)
        {
            cin>>x>>y;
            cout<<query_path(x, y)%p<<endl;
        }
        else if(op == 3)
        {
            cin>>x>>z;
            modify_tree(x, z);
        }
        else if(op == 4)
        {
            cin>>x;
            cout<<query_tree(x)%p<<endl;
        }
    }
}

2021/4/17 22:21
加载中...