#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
//data structures
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<ll> vll;
typedef vector<ld> vld;
typedef pair<long long, long long> pll;
typedef pair<char, int> ci;
typedef pair<string, int> si;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<vector<int>> vvi;
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define sz(a) ((int)a.size())
#define fi first
#define se second
#define whole(v) v.begin(), v.end()
#define rwhole(v) v.rbegin(), v.rend()
#define fro front
#define pqueue priority_queue
#define ubound upper_bound
#define lbound lower_bound
#define beg(v) v.begin()
//bit operations
int flip(int x){
return ~(x) ^ (1 << 32);
}
int allon(int x){
return (1LL << x) - 1;
}
bool bit(ll a, ll i){
return (1LL << i) & a;
}
#define llpc(x) __builtin_popcountll(x)
#define ipc(x) __builtin_popcount(x)
#define iclz(x) __builtin_clz(x)
#define llclz(x) __builtin_clzll(x)
#define ictz(x) __builtin_ctz(x)
#define llctz(x) __builtin_ctzll(x)
//answers
#define cYES cout << "YES" << endl
#define cYes cout << "Yes" << endl
#define cyes cout << "yes" << endl
#define cNO cout << "NO" << endl
#define cNo cout << "No" << endl
#define cno cout << "no" << endl
#define ipsb cout << -1 << endl
const ll mod2 = 998244353;
const ll mod = 1000000007;
const int inf = int(1e9); // ll inf = ll(1e18);
// read arr vec matr etc
#define fill(x, y) memset(x, y, sizeof(x))
void read(vector<int> &x){
for(auto &e:x) cin >> e;
}
void sread(vector<string> &x){
for(auto &e:x) cin >> e;
}
void mread(vector<vector<int>> &p, int nnn, int mmm){
for(int i = 0; i < nnn; ++i){
vector<int> pp;
for(int j = 0; j < mmm; ++j){
int wq; cin >> wq; pp.pb(wq);
}
p.pb(pp);
}
}
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); //high quality random number generator using time as seed
//int random(int l, int r){return uniform_int_distribution<int>(l,r)(rng);} //returns a randomb number between [l, r]
// Solution
struct sparse{
vvi st;
sparse(vi &a){
st.assign(sz(a), vi(21, 0));
for(int i = 0; i < sz(a); ++i){
if(a[i] == -1){
st[i][0] = i;
}else
st[i][0] = a[i]-1;
}
for(int bit = 1; bit < 21; ++bit){
for(int i = 0; i < sz(a); ++i){
st[i][bit] = st[st[i][bit-1]][bit-1];
}
}
}
int lca(int a, int b, vi &depth){
if(a == b){
return a;
}
if(depth[a] < depth[b])swap(a, b); // a is deeper
for(int bit = 20; bit >= 0; --bit){
if(depth[st[a][bit]] > depth[b]){
a = st[a][bit];
}
}
a = st[a][0]; // same depth
if(a == b){
return a;
}
for(int bit = 20; bit >= 0; --bit){
if(st[a][bit] != st[b][bit]){
a = st[a][bit];
b = st[b][bit];
}
}
return st[a][0];
}
};
/*struct sparsesum{
vvi st;
vvi sum;
sparsesum(){
}
sparsesum(vii &a){
st.assign(sz(a), vi(21, 0));
sum.assign(sz(a), vi(21, 0));
for(int i = 0; i < sz(a); ++i){
if(a[i].fi == -1){
st[i][0] = i;
sum[i][0] = 0;
}else{
st[i][0] = a[i].fi;
sum[i][0] = a[i].se;
}
}
for(int bit = 1; bit < 21; ++bit){
for(int i = 0; i < sz(a); ++i){
st[i][bit] = st[st[i][bit-1]][bit-1];
sum[i][bit] = sum[i][bit-1] + sum[st[i][bit-1]][bit-1];
}
}
}
ii lca(int a, int b, vi &depth){
if(a == b){
return {0, 0};
}
if(depth[a] < depth[b])swap(a, b); // a is deeper
int ans = 0;
int an = 0;
//cout << a << " " << b << endl;
for(int bit = 20; bit >= 0; --bit){
if(depth[st[a][bit]] > depth[b]){
ans += sum[a][bit];
a = st[a][bit];
}
}
ans += sum[a][0];
a = st[a][0]; // same depth
//cout << ans << " " << an << " " << a << endl;
if(a == b){
return {ans, an};
}
for(int bit = 20; bit >= 0; --bit){
if(st[a][bit] != st[b][bit]){
ans += sum[a][bit];
an += sum[b][bit];
a = st[a][bit];
b = st[b][bit];
}
}
//cout << ans << " " << an << endl;
return (ii){ans + sum[a][0], an + sum[b][0]};
}
};
struct graph{
vi depths;
vii ed;
sparsesum stt;
graph(vi &depth){
depths = depth;
ed.assign(sz(depth), {-1, -1});
}
void join(int v, int u, int vans, int uans, sparse &st){
int lca = st.lca(u, v, depths);
//cout << u << " " << v << " " << lca << " " << depths[u] << " " << depths[v] << " " << depths[lca] << endl;
ed[v] = {lca, vans};
//cout << ed[u].fi << " " << ed[u].se << " " << ed[v].fi << " " << ed[v].se << endl;
if(ed[u] == ii(-1, -1)){
ed[u] = {lca, uans};
if(ed[u].first == u){
ed[u] = {-1, -1};
}
if(ed[v].first == v){
ed[v] = {-1, -1};
}
return;
}
while(ed[u].first != -1 && depths[u] > depths[lca] && (depths[ed[u].first] > depths[lca])){
uans -= ed[u].second;
u = ed[u].first;
}
if(lca == ed[u].first || lca == u){
if(ed[u].first == u){
ed[u] = {-1, -1};
}
if(ed[v].first == v){
ed[v] = {-1, -1};
}
return;
}
if(ed[u] == ii(-1, -1)){
ed[u] = {lca, uans};
}else{
ii fat = ed[u];
ed[u] = {lca, uans};
if(fat == (ii){-1, -1}){
ed[lca] = {-1, -1};
}else{
ed[lca] = {fat.first, fat.second - uans};
}
}
//cout << ed[u].fi << " " << ed[u].se << " " << ed[v].fi << " " << ed[v].se << endl;
if(ed[u].first == u){
ed[u] = {-1, -1};
}
if(ed[v].first == v){
ed[v] = {-1, -1};
}
}
void create(){
sparsesum sttt(ed);
stt = sttt;
}
int answer(int u, int v){
ii ans = stt.lca(u, v, depths);
return ans.fi + ans.se;
}
};*/
vi nodes;
void dfs(int no, int fat, int depth, vi &depths, vvi &ed){
nodes.pb(no);
depths[no] = depth;
for(auto e:ed[no]){
if(e == fat){
continue;
}
dfs(e, no, depth+1, depths, ed);
}
}
void tc(){
int n, k, q, t; cin >> n >> k >> q >> t;
vi a(n), b(n);
read(a); read(b);
vvi eda(n);
int root = 0;
int roo = 0;
for(int i = 0; i < n; ++i){
if(a[i] == -1){
root = i;
}else{
eda[a[i]-1].pb(i);
eda[i].pb(a[i]-1);
}
}
vi rootdist(n, 0);
rootdist[root] = 0;
vi da(n);
vi db(n);
vvi edb(n);
for(int i = 0; i < n; ++i){
if(b[i] == -1){
roo = i;
}else{
edb[b[i]-1].pb(i);
edb[i].pb(b[i]-1);
}
}
dfs(roo, -1, 0, db, edb);
nodes.clear();
dfs(root, -1, 0, da, eda);
while(sz(nodes) > k){
nodes.pop_back();
}
sparse sta(a);
sparse stb(b);
for(int i = 0; i < sz(nodes); ++i){
cout << nodes[i]+1 << ((i != sz(nodes)-1)? " ":"\n");
}
//fflush(stdout);
//cout.flush();
cout << flush;
vii queries;
for(int i = 1; i < sz(nodes); ++i){
cout << "? " << nodes[i]+1 << " " << nodes[0]+1 << "\n";
//cout.flush();
queries.pb({i, 0});
}
cout << "!\n";
//fflush(stdout);
//cout.flush();
cout << flush;
//graph setree(db);
for(int i = 0; i < sz(queries); ++i){
int e, f, g, h; cin >> e >> f >> g >> h;
int u = nodes[queries[i].fi];
int v = nodes[queries[i].se];
int uu = u;
int vv = v;
int fitreev = sta.lca(u, v, da);
rootdist[u] = rootdist[fitreev] + e; // calculates all distance from root on the first tree(the joint one)
//setree.join(uu, vv, g, h, stb); //uses graph structure to create the lca tree from the second tree, join erase a big edge, add a node, and join 2 small edges to the initial points
}
//setree.create(); //crate sum sparse table
vii query;
for(int i = 0; i < t; ++i){
int u, v; cin >> u >> v;
u--;
v--;
int lca = sta.lca(u, v, da);
ii ans;
ans.fi = rootdist[u] + rootdist[v] - 2 * rootdist[lca];
//ans.se = setree.answer(u, v);
query.pb(ans);
}
for(auto e:query){
cout << e.fi << " " << e.fi << "\n";
}
//fflush(stdout);
//cout.flush();
cout << flush;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t = 1;
while(t--){
tc();
}
}
Compilation message (stderr)
Main.cpp: In function 'int flip(int)':
Main.cpp:38:22: warning: left shift count >= width of type [-Wshift-count-overflow]
38 | return ~(x) ^ (1 << 32);
| ~~^~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |