QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1614#949959#8616. Fast Tree QueriesAlliy666Alliy666Failed.2025-03-24 17:18:002025-03-24 17:18:00

Details

Extra Test:

Accepted
time: 863ms
memory: 19584kb

input:

100000 100000
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
30 31
31 32
32 33
33 34
34 35
35 36
36 37
37 38
38 39
39 40
40 41
41 42
42 43
43 44
44 45
45 46
46 47
47 48
48 49
49 50
50 51
51 ...

output:

100000
100001
100003
100000
100004
100001
100007
100000
100008
100001
100011
100000
100012
100001
100015
100000
100016
100001
100019
100000
100020
100001
100023
100000
100024
100001
100027
100000
100028
100001
100031
100000
99968
100001
99971
100000
99972
100001
99975
100000
99976
100001
99979
10000...

result:

ok 100000 numbers

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#949959#8616. Fast Tree QueriesAlliy666AC ✓1356ms19200kbC++262.0kb2025-03-24 17:11:422025-03-24 17:11:42

answer

#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
const int maxn = 1e5+ 5;
vector<int> G[maxn];
int sz[maxn],fa[maxn],dep[maxn],zson[maxn],top[maxn],dfn[maxn],vis=1,a[maxn];
void dfs(int d)
{
    dep[d]=dep[fa[d]]+1;
    sz[d]=1;
    for (auto i:G[d])
    {
        if (i!=fa[d])
        {
            fa[i]=d;
            dfs(i);
            sz[d]+=sz[i];
            if (sz[i]>sz[zson[d]])
                zson[d]=i;
        }
    }
}
void gettop(int d,int tp)
{
    top[d]=tp;
    dfn[d]=vis;
    a[vis]=d;
    vis++;
    if (zson[d])
        gettop(zson[d],tp);
    for (auto i:G[d])
        if (i!=fa[d]&&i!=zson[d])
            gettop(i,i);
}

void add2(int l,int r,int w)
{
    for (int i=l;i<=r;i++)
        a[i]+=w;
}

void add1(int x,int y,int z) //从x到y最短路径所有节点加z
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        add2(dfn[top[x]],dfn[x],z);
        x=fa[top[x]];
    }
    add2(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),z);
}
int sum(int l,int r)
{
    int ans=0;
    for (int i=l;i<=r;i++)
        ans^=a[i];
    return ans;
}
int query1(int x,int y) //求x到y最短路径所有节点权值和
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        ans^=sum(dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    ans^=sum(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]));
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n,q,u,v,w;
    char op;
    cin>>n>>q;
    for (int i=1;i<n;i++)
    {
        cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1);
    gettop(1,1);
    while (q--)
    {
        cin>>op>>u>>v;
        if (op=='+')
        {
            cin>>w;
            add1(u,v,w);
        }
        else
            cout<<query1(u,v)<<'\n';
    }
}