답안 #824855

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
824855 2023-08-14T11:13:18 Z grogu Tourism (JOI23_tourism) C++14
0 / 100
5000 ms 15692 KB
#define here cerr<<"===========================================\n"
#define dbg(x) cerr<<#x<<": "<<x<<endl;
#include <bits/stdc++.h>
#define ld double
#define ll int
#define ull unsigned long long
#define llinf 100000000000000000LL // 10^17
#define iinf 2000000000 // 2*10^9
#define pb push_back
#define eb emplace_back
#define popb pop_back
#define fi first
#define sc second
#define endl '\n'
#define pii pair<int,int>
#define pll array<ll,3>
#define pld pair<ld,ld>
#define all(a) a.begin(),a.end()
#define ceri(a,l,r) {cerr<<#a<<": ";for(ll i_ = l;i_<=r;i_++) cerr<<a[i_]<< " ";cerr<<endl;}
#define cer(a) {cerr<<#a<<": ";for(ll x_ : a) cerr<<x_<< " ";cerr<<endl;}
#define si(a) (ll)(a.size())
using namespace std;


#define maxn 100005
#define lg 21
ll n,m,q;
vector<ll> g[maxn];
ll st[lg][maxn];
ll in[maxn],out[maxn],ti = 0;
ll rev[maxn];
ll dub[maxn];
ll c[maxn];
pll a[maxn];
void dfs(ll u,ll p){
    st[0][u] = p;
    dub[u] = dub[p] + 1;
    in[u] = ++ti;
    rev[ti] = u;
    for(ll s : g[u]){
        if(s==p) continue;
        dfs(s,u);
    }
    out[u] = ti-1;
}
bool intree(ll x,ll y){return in[y]<=in[x]&&out[y]>=out[x];}
ll lca(ll x,ll y){
    if(intree(x,y)) return y;
    if(intree(y,x)) return x;
    for(ll j = lg-1;j>=0;j--){
        if(!intree(x,st[j][y])) y = st[j][y];
    }
    return st[0][y];
}
ll dis(ll x,ll y){
    return dub[x] + dub[y] - 2*dub[lca(x,y)];
}
ll d = 300;
bool cmp(pll x,pll y){
    if(x[0]/d!=y[0]/d) return x[0]/d<y[0]/d;
    return x[1]<y[1];
}
multiset<ll> s;
ll ans = 0;
ll t[2*maxn],ls[2*maxn],rs[2*maxn],tsz = 0,root = 0;
void init(ll &v,ll tl,ll tr){
    if(!v) v = ++tsz;
    if(tl==tr) return;
    ll mid = (tl+tr)/2;
    init(ls[v],tl,mid);
    init(rs[v],mid+1,tr);
}
void upd(ll v,ll tl,ll tr,ll i,ll x){
    if(tl==tr){t[v]+=x;return;}
    ll mid = (tl+tr)/2;
    if(i<=mid) upd(ls[v],tl,mid,i,x);
    else upd(rs[v],mid+1,tr,i,x);
    t[v] = t[ls[v]] + t[rs[v]];
}
ll getr(ll v,ll tl,ll tr,ll i){
    if(tr<=i) return n+1;
    ll mid = (tl+tr)/2;
    if(tl>i){
        if(t[v]==0) return n+1;
        if(tl==tr) return tl;
        if(t[ls[v]]) return getr(ls[v],tl,mid,i);
        return getr(rs[v],mid+1,tr,i);
    }
    return min(getr(ls[v],tl,mid,i),getr(rs[v],mid+1,tr,i));
}
ll getl(ll v,ll tl,ll tr,ll i){
    if(tl>=i) return -1;
    ll mid = (tl+tr)/2;
    if(tr<i){
        if(t[v]==0) return -1;
        if(tl==tr) return tl;
        if(t[rs[v]]) return getl(rs[v],mid+1,tr,i);
        return getl(ls[v],tl,mid,i);
    }
    return max(getl(ls[v],tl,mid,i),getl(rs[v],mid+1,tr,i));
}
void add(ll i){
    ll x = c[i];
    ll y = getl(root,1,n,in[x]);
    ll z = getr(root,1,n,in[x]);
    if(z==n+1) z = -1;
    upd(root,1,n,in[x],1);
    if(y!=-1) y = rev[y];
    if(z!=-1) z = rev[z];
    if(y!=-1) ans+=dis(x,y);
    if(z!=-1) ans+=dis(x,z);
    if(z!=-1&&y!=-1) ans-=dis(z,y);
}
void del(ll i){
    ll x = c[i];
    ll y = getl(root,1,n,in[x]);
    ll z = getr(root,1,n,in[x]);
    if(z==n+1) z = -1;
    if(y!=-1) y = rev[y];
    if(z!=-1) z = rev[z];
    upd(root,1,n,in[x],-1);
    if(y!=-1) ans-=dis(x,y);
    if(z!=-1) ans-=dis(x,z);
    if(z!=-1&&y!=-1) ans+=dis(z,y);
}
ll rez[maxn];
int main(){
	ios_base::sync_with_stdio(false);cerr.tie(0);cout.tie(0);cin.tie(0);
    cin >> n >> m >> q;
    for(ll i = 1;i<=n-1;i++){
        ll x,y; cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }
    init(root,1,n);
    dfs(1,1);
    for(ll j = 1;j<lg;j++) for(ll i = 1;i<=n;i++) st[j][i] = st[j-1][st[j-1][i]];
    for(ll i = 1;i<=m;i++) cin >> c[i];
    for(ll i = 1;i<=q;i++) cin >> a[i][0] >> a[i][1];
    for(ll i = 1;i<=q;i++) a[i][2] = i;
    sort(a+1,a+1+q,cmp);
    ll tl = 1,tr = 1;
    add(1);
    for(ll i = 1;i<=q;i++){
        while(tr<a[i][1]) add(++tr);
        while(tl>a[i][0]) add(--tl);
        while(tl<a[i][0]) del(tl++);
        while(tr>a[i][1]) del(tr--);
        ll y = getr(root,1,n,0);
        ll z = getl(root,1,n,n+1);
        y = rev[y]; z = rev[z];
        rez[a[i][2]] = ans + dis(y,z);
    }
    for(ll i = 1;i<=q;i++){
        cout<<rez[i]/2 + 1<<endl;
    }
	return (0-0);
}
/**
7 6 2
1 2
1 3
2 4
2 5
3 6
3 7
2 3 6 4 5 7
1 3
4 6
**/
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2772 KB Output is correct
2 Correct 2 ms 2772 KB Output is correct
3 Incorrect 1 ms 2772 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2772 KB Output is correct
2 Correct 2 ms 2772 KB Output is correct
3 Incorrect 1 ms 2772 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2808 KB Output is correct
2 Correct 2 ms 2772 KB Output is correct
3 Correct 4 ms 2876 KB Output is correct
4 Execution timed out 5042 ms 15692 KB Time limit exceeded
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2772 KB Output is correct
2 Incorrect 213 ms 11848 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2772 KB Output is correct
2 Correct 2 ms 2772 KB Output is correct
3 Correct 4 ms 2784 KB Output is correct
4 Execution timed out 5054 ms 13508 KB Time limit exceeded
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2772 KB Output is correct
2 Correct 2 ms 2772 KB Output is correct
3 Incorrect 1 ms 2772 KB Output isn't correct
4 Halted 0 ms 0 KB -