[Codechef - AASHRAM] Gaithonde葉Aashram - セグメントツリー、DFS配列

[Codechef - AASHRAM] Gaithonde Aashram葉

説明

ノードをルートツリー与えられ、「N」ノードツリー、各ノード「U」と重み[U]は関連しています。また、木にクエリの2種類を行うことができます。クエリの数は、「M」です。

  1. 1 Uヴァル:クエリタイプ1は、ノードは、「U」と整数ヴァル説明します。=サブツリーと、すべてのノードのサブツリーの重み付け和で(「U」を含む)を設定します。ノード「U」サブツリーとの和を加えるが偶数である場合には、各ノードヴァル「U」サブツリー(「U」を含むノード)は、そうでない場合は1ノードであっ(サブツリーの各ノードに追加されます'U')。

  2. 2 UV:クエリの2種類は、2つのノード「U」と「V」を説明すると、「U」と「V」及びサブツリービットXOR印刷されなければなりません。

解決

DFSはそれを行うため。

SBは、私が実際にサンプルを持っていた抗DFSの結果とメインプログラムを入れて......

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;

namespace seg
{
int val[N],tag[N];

void pushup(int p)
{
    val[p]=val[p*2]+val[p*2+1];
}
void pushdown(int p,int l,int r)
{
    if(tag[p])
    {
        tag[p*2]+=tag[p];
        tag[p*2+1]+=tag[p];
        val[p*2]+=tag[p]*((l+r)/2-l+1);
        val[p*2+1]+=tag[p]*(r-(l+r)/2);
        tag[p]=0;
    }
}
void build(int p,int l,int r,int *src)
{
    if(l==r)
    {
        val[p]=src[l];
    }
    else
    {
        build(p*2,l,(l+r)/2,src);
        build(p*2+1,(l+r)/2+1,r,src);
        pushup(p);
    }
}
void modify(int p,int l,int r,int ql,int qr,int v)
{
    if(l>qr || r<ql)
        return;
    if(l>=ql && r<=qr)
    {
        val[p]+=v*(r-l+1);
        tag[p]+=v;
    }
    else
    {
        pushdown(p,l,r);
        modify(p*2,l,(l+r)/2,ql,qr,v);
        modify(p*2+1,(l+r)/2+1,r,ql,qr,v);
        pushup(p);
    }
}
int query(int p,int l,int r,int ql,int qr)
{
    if(l>qr || r<ql)
        return 0;
    if(l>=ql && r<=qr)
        return val[p];
    else
    {
        pushdown(p,l,r);
        return query(p*2,l,(l+r)/2,ql,qr) + query(p*2+1,(l+r)/2+1,r,ql,qr);
    }
}
}

namespace tree
{
vector <int> g[N];
int dfn[N],fin[N],vis[N],ind=0,n;

void link(int p,int q)
{
    g[p].push_back(q);
    g[q].push_back(p);
}

void dfs(int p)
{
    vis[p]=1;
    dfn[p]=++ind;
    for(int i=0; i<g[p].size(); i++)
    {
        if(vis[g[p][i]]==0)
        {
            dfs(g[p][i]);
        }
    }
    fin[p]=ind;
}

void presolve()
{
    memset(vis,0,sizeof vis);
    dfs(1);
}

int query(int p)
{
    return seg::query(1,1,n,dfn[p],fin[p]);
}

void modify(int p,int v)
{
    seg::modify(1,1,n,dfn[p],fin[p],v);
}
}

int n,m,t1,t2,t3,t4;
int v[N],src[N];

signed main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1; i<=n; i++)
    {
        cin>>v[i];
    }
    for(int i=1; i<n; i++)
    {
        cin>>t1>>t2;
        tree::link(t1,t2);
    }
    tree::presolve();
    tree::n=n;
    for(int i=1; i<=n; i++)
    {
        src[tree::dfn[i]]=v[i];
    }
    seg::build(1,1,n,src);
    for(int i=1; i<=m; i++)
    {
        cin>>t1>>t2>>t3;
        if(t1==1)
        {
            if(tree::query(t2)%2ll)
            {
                tree::modify(t2,1);
            }
            else
            {
                tree::modify(t2,t3);
            }
        }
        else
        {
            cout<<(tree::query(t2) ^ tree::query(t3))<<endl;
        }
    }
}

おすすめ

転載: www.cnblogs.com/mollnn/p/11736348.html