Submission #892094

# Submission time Handle Problem Language Result Execution time Memory
892094 2023-12-24T21:34:42 Z CutSandstone Railway (BOI17_railway) C++17
36 / 100
68 ms 23752 KB
#include <bits/stdc++.h>
// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt,tune=native")
#define vi vector<int>
#define vb vector<bool>
#define vl vector<long long>
#define vii vector<vector<int>>
#define vll vector<vector<long long>>
#define pi pair<int, int>
#define pl pair<ll, ll>
#define vpi vector<pair<int, int>>
#define vpl vector<pair<ll, ll>>
#define a first
#define b second
#define str string
#define pb push_back
#define hset unordered_set
#define hmap unordered_map
const int mod = 1e9+7;
const int m = 998244353;
//16094558932
using namespace std;
using ll = long long;
using ull = unsigned ll;
template<size_t SZ> struct RMQ {
	static constexpr int level(int x) { return 31-__builtin_clz(x); }
	array<array<int,SZ>, level(SZ)+1> jmp;
	vi v;
	void init(const vi& depth, const vi& ind){
		v = depth;
		assert(ind.size() <= SZ);
		copy(begin(ind), end(ind), begin(jmp[0]));
		for (int j = 1; 1<<j <= ind.size(); ++j)
			for(int i = 0; i<ind.size()-(1<<j)+1; i++){
				int a = jmp[j-1][i], b = jmp[j-1][i+(1<<(j-1))];
				jmp[j][i] = depth[a] < depth[b] ? a:b;
			}
	}
	int query(int l, int r) {
		if(l > r) swap(l, r);
		int d = level(r-l+1);
		int a = jmp[d][l], b = jmp[d][r-(1<<d)+1];
		return v[a] < v[b] ? a:b;
	}
};
struct BIT {
	int N; vl data;
	void init(int sz){N = sz+1; data.resize(sz+1, 0); }
	void add(int p, ll x) { for (p++;p<=N;p+=p&-p) data[p-1] = (data[p-1]+x)%m; }
	ll sum(int l, int r) { return (sum(r)-(l==0?0:sum(l-1))+m)%m; }
	ll sum(int r) { ll s = 0; r++; for(;r;r-=r&-r)s = (s+data[r-1])%m; return s; }
	int lower_bound(ll sum) {
		if (sum <= 0) return -1;
		int pos = 0;
		for (int pw = 1<<25; pw; pw >>= 1) {
			int npos = pos+pw;
			if (npos <= N && data[npos-1] < sum)
				pos = npos, sum -= data[pos-1];
		}
		return pos;
	}
};
struct DSU {
	vector<int> e;
	DSU(int N) { e = vector<int>(N, -1); }
 
	// get representive component (uses path compression)
	int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); }
 
	bool same_set(int a, int b) { return get(a) == get(b); }
 
	int size(int x) { return -e[get(x)]; }
 
	bool unite(int x, int y) {  // union by size
		x = get(x), y = get(y);
		if (x == y) return false;
		if (e[x] > e[y]) swap(x, y);
		e[x] += e[y];
		e[y] = x;
		return true;
	}
};
struct Hasher {
	vl h1, h2, p1, p2, v1, v2;
	const ll m1 = 1283, m2 = 2793;
	const ll i1 = 439594703, i2 = 7876835;
	Hasher(string s){
		int n = s.size();
		h1.resize(n);
		h2.resize(n);
		p1.resize(n);
		p2.resize(n);
		v1.resize(n);
		v2.resize(n);
		for(int i = 0; i<n; i++){
			p1[i] = (i?p1[i-1]:i1)*m1%mod;
			p2[i] = (i?p2[i-1]:i2)*m2%mod;
			v1[i] = (i?v1[i-1]:m1)*i1%mod;
			v2[i] = (i?v2[i-1]:m2)*i2%mod;
			h1[i] = ((i?h1[i-1]:0)+p1[i]*(s[i]-'a'+1)%mod)%mod;
			h2[i] = ((i?h2[i-1]:0)+p2[i]*(s[i]-'a'+1)%mod)%mod;
		}
	}
	pi get(int l, int r){
		ll a = (h1[r]-(l?h1[l-1]:0)+mod)%mod;
		ll b = (h2[r]-(l?h2[l-1]:0)+mod)%mod;
		return {(int)(a*v1[l]%mod), (int)(b*v2[l]%mod)};
	}
};
struct SegTree {
	vll mem;
	int n;
	public:
	SegTree(int N){
		n = N;
		mem.resize(n<<1, vl(4));
	}
	void set(int ind, ll val){
		for(mem[ind+=n] = {val,val,val,val}; ind>>=1;) mem[ind] = comb(mem[ind<<1], mem[ind<<1|1]);
	}
	ll get(int l, int r){
		vl L = {}, R = {};
		for(l+=n,r+=n+1;l<r;l>>=1,r>>=1){
			if(l&1) L = comb(L, mem[l++]);
			if(r&1) R = comb(mem[--r], R);
		}
		return comb(L, R)[0];
	}
	private:
	vl comb(vl& l, vl& r){
		if(l.size() == 0) return r;
		if(r.size() == 0) return l;
		return {max({l[0], r[0], l[2]+r[1]}),
				max({l[3]+r[1], l[1]}),
				max({r[3]+l[2], r[2]}),
				l[3]+r[3]
			};
	}
};
class LZST {
private:
    class Node {
    public:
        ll l, r;
        Node *left, *right;
        ll val = 0, max = 0, min = 0, add = 0;
        bool isSet = false;
        Node(ll a, ll b) : l(a), r(b), left(nullptr), right(nullptr) {}
        void set(ll num) {
            isSet = true;
            add = max = min = num;
            val = num * (r - l + 1);
        }
        void addF(ll num) {
            add += num;
            val += num * (r - l + 1);
            max += num;
            min += num;
        }
        void prop() {
            ll mid = (l + r) >> 1;
            if (left == nullptr) left = new Node(l, mid);
            if (right == nullptr) right = new Node(mid + 1, r);
            if (isSet) {
                isSet = false;
                if (l != r) {
                    left->set(add);
                    right->set(add);
                }
            } else if (add != 0) {
                if (l != r) {
                    left->addF(add);
                    right->addF(add);
                }
            }
            add = 0;
        }
        void upd() {
            val = left->val + right->val;
            min = std::min(left->min, right->min);
            max = std::max(left->max, right->max);
        }
    };
    Node* top;
    void set(ll s, ll e, ll num, Node* curr) {
        if (curr->l == s && curr->r == e) {
            curr->set(num);
            return;
        }
        curr->prop();
        if (e <= curr->left->r) set(s, e, num, curr->left);
        else if (s >= curr->right->l) set(s, e, num, curr->right);
        else {
            set(s, curr->left->r, num, curr->left);
            set(curr->right->l, e, num, curr->right);
        }
        curr->upd();
    }
    void add(ll s, ll e, ll num, Node* curr) {
        if (curr->l == s && curr->r == e) {
            curr->addF(num);
            return;
        }
        curr->prop();
        if (e <= curr->left->r) add(s, e, num, curr->left);
        else if (s >= curr->right->l) add(s, e, num, curr->right);
        else {
            add(s, curr->left->r, num, curr->left);
            add(curr->right->l, e, num, curr->right);
        }
        curr->upd();
    }
    ll sum(ll s, ll e, Node* curr) {
        if (curr->l == s && curr->r == e) return curr->val;
        curr->prop();
        if (e <= curr->left->r) return sum(s, e, curr->left);
        if (s >= curr->right->l) return sum(s, e, curr->right);
        return sum(s, curr->left->r, curr->left) + sum(curr->right->l, e, curr->right);
    }
    ll max(ll s, ll e, Node* curr) {
        if (curr->l == s && curr->r == e) return curr->max;
        curr->prop();
        if (e <= curr->left->r) return max(s, e, curr->left);
        if (s >= curr->right->l) return max(s, e, curr->right);
        return std::max(max(s, curr->left->r, curr->left), max(curr->right->l, e, curr->right));
    }
    ll min(ll s, ll e, Node* curr) {
        if (curr->l == s && curr->r == e) return curr->min;
        curr->prop();
        if (e <= curr->left->r) return min(s, e, curr->left);
        if (s >= curr->right->l) return min(s, e, curr->right);
        return std::min(min(s, curr->left->r, curr->left), min(curr->right->l, e, curr->right));
    }
public:
    LZST(ll N) {
        assert(N > 0);
        top = new Node(0, N - 1);
    }
    ll get(ll s) {
        assert(s >= top->l && s <= top->r);
        Node* curr = top;
        stack<Node*> stk;
        while (curr->l != curr->r) {
            stk.push(curr);
            curr->prop();
            if (s <= curr->left->r) curr = curr->left;
            else curr = curr->right;
        }
        while (!stk.empty()) stk.top()->upd(), stk.pop();
        return curr->val;
    }
    ll sum(ll s, ll e) {
        assert(s >= top->l && s <= top->r && e >= top->l && e <= top->r && s <= e);
        return sum(s, e, top);
    }
    ll max(ll s, ll e) {
        assert(s >= top->l && s <= top->r && e >= top->l && e <= top->r && s <= e);
        return max(s, e, top);
    }
    ll min(ll s, ll e) {
        assert(s >= top->l && s <= top->r && e >= top->l && e <= top->r && s <= e);
        return min(s, e, top);
    }
    void add(ll s, ll e, ll num) {
        assert(s >= top->l && s <= top->r && e >= top->l && e <= top->r && s <= e);
        add(s, e, num, top);
    }
    void add(ll s, ll num) {
        assert(s >= top->l && s <= top->r);
        add(s, s, num, top);
	}
    void set(ll s, ll e, ll num) {
        assert(s >= top->l && s <= top->r && e >= top->l && e <= top->r && s <= e);
        set(s, e, num, top);
    }
    void set(ll s, ll num) {
        assert(s >= top->l && s <= top->r);
        set(s, s, num, top);
    }
};
const string name = "";
const int MAXN = 1e5, LOGN = 18;
vi g[MAXN];
int jp[MAXN][LOGN], timer = 0, tour[MAXN];
int depth[MAXN], st[MAXN], en[MAXN], cnt[MAXN];
int jump(int a, int k){
	for(int i = 0; i<LOGN; i++) 
		if((k>>i)&1) a = jp[a][i];
	return a;
}
int lca(int a, int b){
	if(depth[a] > depth[b]) swap(a, b);
	b = jump(b, depth[b]-depth[a]);
	if(a == b) return a;
	for(int i = LOGN-1; i>=0; i--) if(jp[a][i] != jp[b][i]){
		a = jp[a][i];
		b = jp[b][i];
	}
	return jp[a][0];
}
void dfs1(int s, int p){
	if(p+1) depth[s] = depth[p]+1;
	jp[s][0] = p;
	tour[st[s] = timer++] = s;
	for(int i: g[s]) if(i != p)
		dfs1(i, s);
	en[s] = timer-1;
}
void dfs2(int s, int p){
	for(int i: g[s]) if(i != p)
		dfs2(i, s);
	if(p != -1) cnt[p]+=cnt[s];
}
int main() {
	ios::sync_with_stdio(false);
  	cin.tie(nullptr);
	int n, m, k; cin >> n >> m >> k;
	vpi eg(n-1);
	for(int i = 0; i<n-1; i++){
		int a, b; cin >> a >> b;
		g[--a].pb(--b);
		g[b].pb(a);
		eg[i] = {a, b};
	}
	for(int i = 0; i<n; i++) for(int j = 0; j<LOGN; j++) jp[i][j] = -1;
	dfs1(0, -1);
	for(int i = 1; i<LOGN; i++) for(int j = 0; j<n; j++)
		if(jp[j][i-1] != -1) jp[j][i] = jp[jp[j][i-1]][i-1];
	while(m--){
		int total, top; cin >> total >> top;
		set<int> in;
		in.insert(st[--top]);
		while(--total){
			int s; cin >> s;
			int g = lca(--s, top);
			if(g == top){
				auto low = in.lower_bound(st[s]);
				auto high = low--;
				int end = -1;
				if(high != in.begin()) end = lca(s, tour[*low]);
				if(high != in.end()){
					int t = lca(s, tour[*high]);
					if(end == -1 || depth[t] > depth[end]) end = t;
				}
				cnt[s]++;
				cnt[end]--;
			}else{
				cnt[top]++;
				cnt[s]++;
				cnt[g]-=2;
				top = g;
			}
			in.insert(st[s]);
		}
	}
	dfs2(0, -1);
	vi edge(n);
	for(int i = 0; i<n-1; i++) if(depth[eg[i].a] > depth[eg[i].b])
		edge[eg[i].a] = i+1; else edge[eg[i].b] = i+1;
	vi ans;
	for(int i = 0; i<n; i++) if(cnt[i] >= k) ans.pb(edge[i]);
	cout << ans.size() << "\n";
	for(int i: ans) cout << i << " ";
	cout << "\n";
}
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 5464 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 5464 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 55 ms 23536 KB Output is correct
2 Correct 1 ms 5220 KB Output is correct
3 Correct 54 ms 23092 KB Output is correct
4 Correct 54 ms 22612 KB Output is correct
5 Correct 67 ms 23500 KB Output is correct
6 Correct 67 ms 23752 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 46 ms 20088 KB Output is correct
2 Correct 53 ms 18056 KB Output is correct
3 Correct 61 ms 17748 KB Output is correct
4 Correct 58 ms 17868 KB Output is correct
5 Correct 47 ms 17772 KB Output is correct
6 Correct 51 ms 20308 KB Output is correct
7 Correct 46 ms 20304 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 46 ms 20088 KB Output is correct
2 Correct 53 ms 18056 KB Output is correct
3 Correct 61 ms 17748 KB Output is correct
4 Correct 58 ms 17868 KB Output is correct
5 Correct 47 ms 17772 KB Output is correct
6 Correct 51 ms 20308 KB Output is correct
7 Correct 46 ms 20304 KB Output is correct
8 Correct 59 ms 20392 KB Output is correct
9 Correct 68 ms 20376 KB Output is correct
10 Correct 65 ms 23496 KB Output is correct
11 Correct 66 ms 23460 KB Output is correct
12 Incorrect 50 ms 17696 KB Output isn't correct
13 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 5464 KB Output isn't correct
2 Halted 0 ms 0 KB -