玄学问题2(结果不一样)

P3384 【模板】重链剖分/树链剖分

Harmonic_qwq @ 2023-02-17 19:55:41

这段代码开O2A了,不开O2则10pts,为什么

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
struct edge
{
    int v,next;
} tree[maxn];
int head[maxn] = {0},cnt1 = 0,cnt2 = 0;
void add(int u,int v)
{
    tree[++cnt1].v = v;
    tree[cnt1].next = head[u];
    head[u] = cnt1;
    return;
}
int deep[maxn],top[maxn],fa[maxn] = {0},size[maxn] = {0},hson[maxn] = {0},dfn[maxn],rnk[maxn],a[maxn],mod;
void dfs1(int root)
{
    size[root] = 1;
    for(int f = head[root]; f; f = tree[f].next)
    {
        if(tree[f].v == fa[root])continue;
        fa[tree[f].v] = root;
        deep[tree[f].v] = deep[root]+1;
        dfs1(tree[f].v);
        size[root] += size[tree[f].v];
        if(size[hson[root]]<size[tree[f].v])hson[root] = tree[f].v;
    }
    return;
}
void dfs2(int root,int t)
{
    top[root] = t;
    dfn[root] = ++cnt2;
    rnk[cnt2] = root;
    if(hson[root])dfs2(hson[root],t);
    for(int f = head[root]; f; f = tree[f].next)if(tree[f].v != hson[root]&&tree[f].v != fa[root])dfs2(tree[f].v,tree[f].v);
    return;
}
struct node
{
    int left,right;
    long long data,lazy;
} tr[maxn<<1];
void build(int root,int l,int r)
{
    tr[root].lazy = 0;
    tr[root].left = l;
    tr[root].right = r;
    if(l == r)tr[root].data = a[rnk[l]];
    else
    {
        int mid = (l+r)>>1;
        build(root<<1,l,mid);
        build(root<<1|1,mid+1,r);
        tr[root].data = (tr[root<<1].data+tr[root<<1|1].data)%mod;
    }
    return;
}
void push_down(int root)
{
    if(tr[root].lazy&&tr[root].left != tr[root].right)
    {
        tr[root<<1].lazy += tr[root].lazy;
        tr[root<<1|1].lazy += tr[root].lazy;
        tr[root<<1].data = (tr[root<<1].data+tr[root].lazy*(tr[root<<1].right-tr[root<<1].left+1))%mod;
        tr[root<<1|1].data = (tr[root<<1|1].data+tr[root].lazy*(tr[root<<1|1].right-tr[root<<1|1].left+1))%mod;
        tr[root].lazy = 0;
    }
    return;
}
void modify(int root,int l,int r,int k)
{
    if(l<=tr[root].left&&r>=tr[root].right)
    {
        tr[root].data = (k*(tr[root].right-tr[root].left+1)+tr[root].data)%mod;
        tr[root].lazy += k;
        return;
    }
    push_down(root);
    if(tr[root<<1].right>=l)modify(root<<1,l,r,k);
    if(tr[root<<1|1].left<=r)modify(root<<1|1,l,r,k);
    tr[root].data = (tr[root<<1].data+tr[root<<1|1].data)%mod;
    return;
}
long long query(int root,int l,int r)
{
    if(l<=tr[root].left&&r>=tr[root].right)return tr[root].data;
    push_down(root);
    long long ret = 0;
    if(tr[root<<1].right>=l)ret=(ret+query(root<<1,l,r))%mod;
    if(tr[root<<1|1].left<=r)ret=(ret+query(root<<1|1,l,r))%mod;
    return ret;
}
void lca_modify(int x,int y,int k)
{
    while (top[x] != top[y])
    {
        if(deep[top[x]]<deep[top[y]])
        {
            modify(1,dfn[top[y]],dfn[y],k);
            y = fa[top[y]];
        }
        else
        {
            modify(1,dfn[top[x]],dfn[x],k);
            x = fa[top[x]];
        }
    }
    if(deep[x]>deep[y])modify(1,dfn[y],dfn[x],k);
    else modify(1,dfn[x],dfn[y],k);
    return;
}
long long lca_query(int x,int y)
{
    long long ret = 0;
    while (top[x] != top[y])
    {
        if(deep[top[x]]<deep[top[y]])
        {
            ret += query(1,dfn[top[y]],dfn[y]);
            ret %= mod;
            y = fa[top[y]];
        }
        else
        {
            ret += query(1,dfn[top[x]],dfn[x]);
            ret %= mod;
            x = fa[top[x]];
        }
    }
    if(deep[x]>deep[y])ret += query(1,dfn[y],dfn[x]);
    else ret += query(1,dfn[x],dfn[y]);
    return ret%mod;
}
int main()
{
#ifdef WIN32
    freopen("D:\\luogu.in", "r", stdin);
    freopen("d:\\luogu.out", "w", stdout);
#endif
    int n,m,r;
    scanf("%d%d%d%d",&n,&m,&r,&mod);
    for(int f = 1; f<=n; f++)scanf("%d",&a[f]);
    for(int f = 1; f<n; f++)
    {
        int r1,r2;
        scanf("%d%d",&r1,&r2);
        add(r1,r2);
        add(r2,r1);
    }
    dfs1(r);
    dfs2(r,r);
    build(1,1,n);
    for(int q = 0; q<m; q++)
    {
        char r1 = getchar();
        r1 = getchar();
        if(r1 == '1')
        {
            int x,y;
            long long k;
            scanf("%d%d%lld",&x,&y,&k);
            lca_modify(x,y,k%mod);
        }
        else if(r1 == '2')
        {
            int x,y;
            scanf("%d%d",&x,&y);
            int ret = lca_query(x,y);
            printf("%d\n",ret);
        }
        else if(r1 == '3')
        {
            int x;
            long long k;
            scanf("%d%11d",&x,&k);
            modify(1,dfn[x],dfn[x]+size[x]-1,k%mod);
        }
        else
        {
            int x;
            scanf("%d",&x);
            int ret = query(1,dfn[x],dfn[x]+size[x]-1);
            printf("%d\n",ret);
        }
    }
    return 0;
}

by olegekei @ 2023-02-17 20:13:25

@zhouyiyu0314

on line 177:

scanf("%d%11d",&x,&k);

改为:

scanf("%d%lld",&x,&k);


by RedLycoris @ 2023-02-17 20:27:08

xswl


by Harmonic_qwq @ 2023-02-17 21:20:30

%%%,不开O2过了,但恕我才疏学浅,看不这两行的区别啊


by Harmonic_qwq @ 2023-02-17 21:23:51

知道了,我是l和1都分不清的蒟蒻(已结帖)


|