Submission #953844

#TimeUsernameProblemLanguageResultExecution timeMemory
953844dwuyTourism (JOI23_tourism)C++14
28 / 100
5068 ms24660 KiB
/**   - dwuy -

      />    フ
      |  _  _|
      /`ミ _x ノ
     /      |
    /   ヽ   ?
 / ̄|   | | |
 | ( ̄ヽ__ヽ_)_)
 \二つ

**/
#include <bits/stdc++.h>

#define fastIO ios_base::sync_with_stdio(false); cin.tie(NULL)
#define file(a) freopen(a".inp","r",stdin); freopen(a".out", "w",stdout)
#define fi first
#define se second
#define endl "\n"
#define len(s) int32_t(s.length())
#define MASK(k)(1LL<<(k))
#define TASK "test"
#define int long long

using namespace std;

typedef tuple<int, int, int> tpiii;
typedef pair<double, double> pdd;
typedef pair<int, int> pii;
typedef long long ll;

const long long OO = 1e18;
const int MOD = 1e9 + 7;
const int INF = 1e9;
const int MX = 100005;

int n, m, q, bsz;
int c[MX], a[MX];
int answer[MX];
tpiii qr[MX];
vector<int> G[MX];

void nhap(){
    cin >> n >> m >> q;
    bsz = sqrt(m);
    for(int i=1; i<n; i++){
        int u, v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i=1; i<=m; i++) cin >> c[i];
    for(int i=1; i<=q; i++){
        int l, r;
        cin >> l >> r;
        qr[i] = {l, r, i};
    }
}

struct Node{
    int cnt, sum;

    Node(){
        this->cnt = 0;
        this->sum = 0;
    }
};

struct SMT{
    int n;
    vector<Node> tree;

    SMT(int n=0){
        this->n = n;
        this->tree.assign(n<<2|3, Node());
    }

    void build(int l, int r, int id){
        if(l == r){
            tree[id].sum = 1;
            tree[id].cnt = 0;
            return;
        }
        int mid = (l + r)>>1;
        int ID = id<<1;
        build(l, mid, ID);
        build(mid+1, r, ID|1);
        tree[id].cnt = 0;
        tree[id].sum = tree[ID].sum + tree[ID|1].sum;
    }

    void build(){
        build(1, n, 1);
    }

    void update(int l, int r, int id, const int &u, const int &v, const int &val){
        if(l>v || r<u) return;
        if(l>=u && r<=v){
            tree[id].cnt += val;
            tree[id].sum = tree[id].cnt? 0 : l!=r? tree[id<<1].sum + tree[id<<1|1].sum : 1;
            return;
        }
        int mid = (l + r)>>1;
        int ID = id<<1;
        update(l, mid, ID, u, v, val);
        update(mid+1, r, ID|1, u, v, val);
        tree[id].sum = tree[id].cnt? 0 : tree[ID].sum + tree[ID|1].sum;
    }

    void update(int l, int r, int val){
        update(1, n, 1, l, r, val);
    }

    int get(int l, int r, int id, const int &u, const int &v){
        if(l>v || r<u) return 0;
        if(l>=u && r<=v) return tree[id].sum;
        int mid = (l+r)>>1;
        if(tree[id].cnt) return 0;
        return get(l, mid, id<<1, u, v) + get(mid+1, r, id<<1|1, u, v);
    }

    int get(int l, int r){
        return get(1, n, 1, l, r);
    }
};

namespace HLD{
    int p[MX];
    int h[MX];
    int num[MX];
    int head[MX];
    int numC[MX];
    int heavy[MX];
    SMT smt(0);

    void dfs(int u){
        h[u] = h[p[u]] + 1;
        heavy[u] = -1;
        for(int v: G[u]) if(v!=p[u]){
            p[v] = u;
            dfs(v);
            numC[u] += numC[v];
            if(heavy[u] == -1 || numC[v] > numC[heavy[u]]) heavy[u] = v;
        }
    }

    int dfsID = 0;
    void dcp(int u, int head){
        num[u] = ++dfsID;
        HLD::head[u] = head;
        if(heavy[u] != -1) dcp(heavy[u], head);
        for(int v: G[u]) if(HLD::head[v] == 0){
            dcp(v, v);
        }
    }

    void build(){
        dfs(1);
        dcp(1, 1);
        smt = SMT(n);
    }

    int LCA(int u, int v){
        if(u==0 || v==0) return max(u, v);
        while(head[u] != head[v]){
            if(h[head[u]] < h[head[v]]) swap(u, v);
            u = p[head[u]];
        }
        return h[u] < h[v]? u : v;
    }

    int get(int u, int v){
        int res = 0;
        if(u == 0) u = v;
        if(v == 0) v = u;
        int puv = LCA(u, v);
        while(head[u] != head[v]){
            if(h[head[u]] < h[head[v]]) swap(u, v);
            res += smt.get(num[head[u]], num[u]);
            u = p[head[u]];
        }
        if(h[u] > h[v]) swap(u, v);
        res += smt.get(num[u], num[v]);
        return res;
    }

    void update(int u, int v, int val){
        if(u == 0) u = v;
        if(v == 0) v = u;
        int puv = LCA(u, v);
        while(head[u] != head[v]){
            if(h[head[u]] < h[head[v]]) swap(u, v);
            smt.update(num[head[u]], num[u], val);
            u = p[head[u]];
        }
        if(h[u] > h[v]) swap(u, v);
        smt.update(num[u], num[v], val);
    }
}

bool comp(const tpiii &a, const tpiii &b){
    int l = get<0>(a), r = get<1>(a);
    int u = get<0>(b), v = get<1>(b);
    return l/bsz != u/bsz? l < u : r < v;
}

void solve(){
    HLD::build();
    sort(qr+1, qr+1+q, comp);
    for(int i=1, j=0, st=0, p=0, ans=0; i<=q; i++){
        int l, r, id;
        tie(l, r, id) = qr[i];
        if(i==1 || l/bsz != get<0>(qr[i-1])/bsz){
            HLD::smt.build();
            j = st = bsz*(l/bsz + 1);
            ans = 0;
            p = 0;
        }
        while(j<=r){
            ans += HLD::get(c[j], p);            
            HLD::update(c[j], p, 1);
            p = HLD::LCA(p, c[j]);
            j++;
        }

        vector<int> tmp;
        tmp.push_back(p);
        int result = ans;
        for(int t=l; t<min(r+1, st); t++){
            result += HLD::get(c[t], tmp.back());
            HLD::update(c[t], tmp.back(), 1);
            tmp.push_back(HLD::LCA(c[t], tmp.back()));
        }
        tmp.pop_back();
        for(int t=min(r, st-1); t>=l; t--){
            HLD::update(c[t], tmp.back(), -1);
            tmp.pop_back();
        }
        answer[id] = result;
    }

    for(int i=1; i<=q; i++) cout << answer[i] << endl;
}

int32_t main(){
    fastIO;
    //file(TASK);

    nhap();
    solve();

    return 0;
}

Compilation message (stderr)

tourism.cpp: In function 'long long int HLD::get(long long int, long long int)':
tourism.cpp:176:13: warning: unused variable 'puv' [-Wunused-variable]
  176 |         int puv = LCA(u, v);
      |             ^~~
tourism.cpp: In function 'void HLD::update(long long int, long long int, long long int)':
tourism.cpp:190:13: warning: unused variable 'puv' [-Wunused-variable]
  190 |         int puv = LCA(u, v);
      |             ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...