Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #pragma GCC optimize (03)
- // #define int long long
- #define ld long double
- #define tii tuple<int,int,int>
- #define tii4 tuple<int,int,int,int>
- #define pii pair<int,int>
- #define ff first
- #define ss second
- #define all(x) x.begin(),x.end()
- #define pb push_back
- #define ppb pop_back
- #define ppf pop_front
- #define mp make_pair
- const int maxn=1e5+5, maxval=1e6+60, INF=0x3f3f3f3f, MOD=1e9+7;
- int depth[maxn], pai[25][maxn], bit[maxval], l[maxn], r[maxn];
- int n;
- vector<int> queries[maxn];
- bool comp_l(int a, int b){
- return l[a] < l[b];
- }
- bool comp_depth(int a, int b){
- return depth[a] < depth[b];
- }
- int find_depth(int u){
- if(u==0) return depth[u]=0;
- if(depth[u]!=0) return depth[u];
- return depth[u] = 1+find_depth(pai[0][u]);
- }
- void upd(int id, int val){
- if(id==0) return;
- for(; id<maxval; id+=id&-id) bit[id]+=val;
- }
- int fquery(int id){
- int rt=0;
- for(; id>0; id-=id&-id) rt+=bit[id];
- return rt;
- }
- int query(int v){
- return !!(fquery(r[v])-fquery(l[v]-1));
- }
- int lca(int a, int b){
- if(depth[a]<depth[b]) swap(a,b);
- int d = depth[a]-depth[b];
- for(int log=0; log<20; log++){
- if(d&(1<<log)) a=pai[log][a];
- }
- if(a==b) return a;
- for(int log=19; log>=0; log--){
- int pa = pai[log][a];
- int pb = pai[log][b];
- if(pa!=pb) a=pa, b=pb;
- }
- return pai[0][a];
- }
- void solve(){
- cin >> n;
- vector<tii4> pontos;
- pontos.pb({0,0,0,0}), pontos.pb({1e6+5,0,1,0});
- for(int i=1; i<=n; i++){
- int a,b,x; cin >> a >> x >> b >> x;
- a++,b++;
- l[i]=a, r[i]=b;
- pontos.pb({a,i,0,0}), pontos.pb({b,i,1,0});
- }
- int q; cin >> q;
- for(int i=0; i<q; i++){
- int k; cin >> k;
- for(int j=0; j<k; j++){
- int x; cin >> x, x++;
- pontos.pb({x,i,0,1});
- }
- }
- sort(all(pontos));
- vector<int> abertos;
- for(auto[pos,id,func, qry] : pontos){
- if(qry){
- assert(abertos.size());
- // if(abertos.back())
- queries[id].pb(abertos.back());
- }
- else if(func==0){
- if(abertos.size()) pai[0][id] = abertos.back();
- abertos.pb(id);
- }
- else abertos.ppb();
- }
- for(int i=1; i<=n; i++){
- if(depth[i]==0) find_depth(i);
- }
- for(int log=1; log<20; log++){
- for(int i=1; i<=n; i++){
- pai[log][i] = pai[log-1][pai[log-1][i]];
- }
- }
- for(int i=0; i<q; i++){
- vector<int> vertex=queries[i];
- sort(all(vertex));
- vertex.erase(unique(all(vertex)), vertex.end());
- // if(vertex.size()==1){
- // cout << 0 << '\n';
- // continue;
- // }
- sort(all(vertex), comp_l);
- int highest_lca=depth[vertex.front()];
- for(int j=0; j<vertex.size()-1; j++){
- highest_lca = min(highest_lca, depth[lca(vertex[j], vertex[j+1])]);
- }
- int ans = -highest_lca;
- // cout << "a" << ans << endl;
- sort(all(vertex), comp_depth);
- reverse(all(vertex));
- for(int x : vertex){
- if(x==0) continue;
- ans += (query(x)==0);
- int cur=x;
- for(int log=19; log>=0; log--){
- int p = pai[log][cur];
- if(p!=0 && !query(p))
- ans += (1<<log), cur = pai[log][cur];
- }
- upd(l[x],1);
- }
- cout << ans << '\n';
- for(int x : vertex) upd(l[x],-1);
- }
- }
- int32_t main(){
- ios::sync_with_stdio(false); cin.tie(0);
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- int t=1;
- // cin >> t;
- while(t--){
- solve();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment