Submission #1281128

#TimeUsernameProblemLanguageResultExecution timeMemory
1281128longdeptraiRailway (BOI17_railway)C++20
100 / 100
133 ms38840 KiB
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
//using namespace __gnu_pbds;
#define LongDepTrai "railway"
#define ll long long
#define int long long
#define ull unsigned long long
#define ld long double
#define ii pair<int,int>
#define iii pair<int,ii>
#define iv pair<ii,ii>
#define pll pair<ll,ll>
#define vi vector<int>
#define vii vector<ii>
#define vll vector<ll>
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) int((x).size())
#define order_set(T) tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>

inline ll add(ll a, ll b, ll mod){ a += b; if(a >= mod) a -= mod; return a; }
inline ll sub(ll a, ll b, ll mod){ a -= b; if(a < 0) a += mod; return a; }
inline ll mul(ll a, ll b, ll mod){ return ( (ll)a * b ) % mod; }

static mt19937_64 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());

const int N=2e5+9;
const int lg=18;
int n, test, a[N], k,par[N][lg+2], tour[N], timer=0,timer2=0, h[N], kval, dist[N], sz[N], tin[N], tout[N],heavy[N],head[N],pos[N];
//vector<ii> v[N];
vector<int> g[N];
int cnt = 0;
bool ok[N];
struct BIT {
    int n;
    vector<long long> bit; // 1-indexed

    BIT(int n=0) { init(n); }

    void init(int _n) {
        n = _n;
        bit.assign(n+1, 0);
    }

    // add `val` to index idx (point update on internal BIT)
    void addPoint(int idx, long long val) {
        for (; idx <= n; idx += idx & -idx) bit[idx] += val;
    }

    // prefix sum up to idx (inclusive)
    long long prefixSum(int idx) const {
        long long s = 0;
        for (; idx > 0; idx -= idx & -idx) s += bit[idx];
        return s;
    }

    // RANGE UPDATE: add val to all positions in [l, r]
    // NOTE: l and r must be 1-indexed and 1 <= l <= r <= n
    void rangeAdd(int l, int r, long long val) {
        if (l > r) return;
        addPoint(l, val);
        if (r+1 <= n) addPoint(r+1, -val);
    }

    // POINT QUERY: get value at position pos (1-indexed)
    long long pointQuery(int pos) const {
        return prefixSum(pos);
    }
} bit;

void dfs(int u, int p) {
	tin[u] = ++timer;
	for (int e : g[u]) {
		int x = e;
		if (x == p) continue;
		h[x] = h[u] + 1;
		//dist[x] = dist[u] + y;
		par[x][0] = u;
		dfs(x, u);
	}
	tout[u] = timer;
}
int dfs2(int u,int p){
    int mx_sz=0;
    int cur_sz=1;

    for(int x:g[u]){
        if(x==p) continue;
      //  h[x]=h[u]+1;
     //   par[x]=u;
        int son_sz=dfs2(x,u);
        if(son_sz>mx_sz){
            mx_sz=son_sz;
            heavy[u]=x;
        }
        cur_sz+=son_sz;
    }
    return cur_sz;
}
void hld(int u,int h){
    head[u]=h;
    pos[u]=++timer2;
    tour[timer2]=u;
    if(heavy[u]) hld(heavy[u],h);
    for(int x:g[u]){
        if(x!=par[u][0] && x!=heavy[u]){
            hld(x,x);
        }
    }
}
void change(int x,int y){
    while(head[x]!=head[y]){
        if(h[head[x]]<h[head[y]]) swap(x,y);
       // Update(1,pos[head[x]],pos[x],1,n,k);
        bit.rangeAdd(pos[head[x]],pos[x],1);
    //    cout<<tour[pos[head[x]]]<<" "<<x<<"\n";
        x=par[head[x]][0];
    }
    if(h[y]<h[x]) swap(x,y);
 //   Update(1,pos[x]+1,pos[y],1,n,k);
    bit.rangeAdd(pos[x]+1,pos[y],1);
  //  cout<<tour[pos[x]+1]<<" "<<tour[pos[y]]<<"\n";
}

int lca(int u, int v) {
	if (h[u] < h[v]) swap(u, v);
	for (int i = lg; i >= 0; i--) {
		if ((h[u] - h[v]) >= (1ll << i)) u = par[u][i];
	}
	if (u == v) return u;
	for (int i = lg; i >= 0; i--) {
		if (par[u][i] != par[v][i]) {
			u = par[u][i];
			v = par[v][i];
		}
	}
	return par[u][0];
}
void prelca() {
	dfs(1, -1);
	for (int j = 1; j <= lg; j++) {
		for (int i = 1; i <= n; i++) {
			par[i][j] = par[par[i][j-1]][j-1];
		}
	}
}
bool ss(int x, int y) {
	return tin[x] < tin[y];
}
bool inside(int x, int y) {
	return (tin[x] <= tin[y] && tin[y] <= tout[x]);
}
int build(vector<int> &ver) {
	sort(ver.begin(), ver.end(), ss);
//	for(int x:ver) cout<<x<<" ";
//	cout<<"\n";
	int p = ver.size();
	for (int i = 0; i < p-1; i++) {
		int z = lca(ver[i], ver[i+1]);
		ver.pb(z);
	}
	sort(ver.begin(), ver.end(), ss);
	ver.erase(unique(ver.begin(), ver.end()), ver.end());

	vector<int> st;
	st.pb(ver[0]);
	for (int i = 1; i < ver.size(); i++) {
		int u = ver[i];
		while(!st.empty() && !inside(st.back(), u)) st.pop_back();
		assert(!st.empty());
		int last = st.back();
		//cout << 0<<" "<<last << " " << u << endl;
		change(last,u);

		//g[last].pb(u);
		st.pb(u);
	}
	return ver[0];
}
void solve(){
    cin >> n >> test>>kval;
    bit.init(n+2);
    vii ed;
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        g[u].pb(v);
        g[v].pb(u);
        ed.pb({u,v});
        //v[u].pb(v);

    }
	prelca();
	dfs2(1,-1);
    hld(1,1);
	for (int Q = 1; Q <= test; Q++) {
		cin >> k;
		vector<int> ver(k);
		for (int i = 0; i < k; i++) {
			cin >> ver[i];
            cnt += ver[i];
//            cout << "! " << ver[i] << " ";
			sz[ver[i]] += ver[i];
		}
		int goc = build(ver);
//        for(int i=2;i<=n;i++){
//            cout<<bit.pointQuery(pos[i])<<" ";
//        }
//        cout<<"\n";
	}
	vi res;
	for(int i=0;i<ed.size();i++){
        int u=ed[i].fi;
        int v=ed[i].se;
        if(h[u]<h[v]) swap(u,v);
        if(bit.pointQuery(pos[u])>=kval){
            res.pb(i+1);
        }
	}
    cout<<res.size()<<"\n";
    for(int x:res) cout<<x<<" ";
}
signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    int t=1;
    while(t--){
        solve();
    }
}
#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...