QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#1612#949959#8616. Fast Tree QueriesAlliy666Alliy666Failed.2025-03-24 17:15:562025-03-24 17:15:59

Details

Extra Test:

Accepted
time: 1151ms
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
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000...

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';
    }
}