2017廣西邀請賽 Query on A Tree (可持續化字典樹)
阿新 • • 發佈:2017-08-31
題意 second for each follow n) nod pair content back
提交: 15 解決: 3
[提交][狀態][討論版]
One day, monkey A learned about one of the bit-operations, xor. He was keen of this interesting operation and wanted to practise it at once.
Monkey A gave a value to each node on the tree. And he was curious about a problem.
The problem is how large the xor result of number x and one node value of label y can be, when giving you a non-negative integer x and a node label u indicates that node y is in the subtree whose root is u(y can be equal to u).
Can you help him?
For each test case there are two positive integers n(2 ≤ n ≤ 105) and q(2 ≤ q ≤ 105), indicating that the tree has n nodes and you need to answer q queries.
Then two lines follow.
The first line contains n non-negative integers V1, V2, ... , Vn(0 ≤ Vi ≤ 109), indicating the value of node i. The root of the tree is node 1.
The second line contains n-1 non-negative integers F1, F2,...Fn−1, Fi(1 ≤ Fi ≤ n) means the father of node i + 1.
And then q lines follow.
In the i-th line, there are two integers u(1 ≤ u ≤ n) and x(0 ≤ x ≤ 109), indicating that the node you pick should be in the subtree of u, and x has been described in the problem.
Query on A Tree
時間限制: 8 Sec 內存限制: 512 MB提交: 15 解決: 3
[提交][狀態][討論版]
題目描述
Monkey A lives on a tree. He always plays on this tree.One day, monkey A learned about one of the bit-operations, xor. He was keen of this interesting operation and wanted to practise it at once.
Monkey A gave a value to each node on the tree. And he was curious about a problem.
Can you help him?
輸入
There are no more than six test cases.For each test case there are two positive integers n(2 ≤ n ≤ 105) and q(2 ≤ q ≤ 105), indicating that the tree has n nodes and you need to answer q queries.
The first line contains n non-negative integers V1, V2, ... , Vn(0 ≤ Vi ≤ 109), indicating the value of node i. The root of the tree is node 1.
The second line contains n-1 non-negative integers F1, F2,...Fn−1, Fi(1 ≤ Fi ≤ n) means the father of node i + 1.
And then q lines follow.
輸出
樣例輸入
2 2
1 2
1
1 3
2 1
樣例輸出
2
3
【題意】給你一棵樹,每個節點有權值,Q次詢問,求u為跟的子樹裏與x亦或後的值最大是多少。
【分析】可持續化字典樹可用來解決一段區間內與x亦或後的值最大是多少,這裏可以用dfs序將子樹轉為序列。
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back #define mp make_pair #define rep(i,l,r) for(int i=(l);i<=(r);++i) #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N = 2e5+5;; const int M = 17; const int mod = 1e9+7; const int mo=123; const double pi= acos(-1.0); typedef pair<int,int>pii; int bin[31]; int n,m,tot; int a[N],root[N],id[N],st[N],ed[N]; vector<int>edg[N]; struct trie{ int cnt; int ch[N*32][2],sum[N*32]; void init(){ met(ch,0);met(sum,0); cnt=0; } int insert(int x,int val){ int tmp,y;tmp=y=++cnt; for(int i=30;i>=0;i--) { ch[y][0]=ch[x][0];ch[y][1]=ch[x][1]; sum[y]=sum[x]+1; int t=val&bin[i];t>>=i; x=ch[x][t]; ch[y][t]=++cnt; y=ch[y][t]; } sum[y]=sum[x]+1; return tmp; } int query(int l,int r,int val){ int tmp=0; for(int i=30;i>=0;i--) { int t=val&bin[i];t>>=i; if(sum[ch[r][t^1]]-sum[ch[l][t^1]]) tmp+=bin[i],r=ch[r][t^1],l=ch[l][t^1]; else r=ch[r][t],l=ch[l][t]; } return tmp; } }trie; void dfs(int u,int fa){ st[u]=++tot; id[tot]=u; for(int i=0;i<edg[u].size();i++){ int v=edg[u][i]; if(v==fa)continue; dfs(v,u); } ed[u]=tot; } int main(){ bin[0]=1;for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1; while(~scanf("%d%d",&n,&m)){ root[0]=0;tot=0; trie.init(); for(int i=1;i<=n;i++)scanf("%d",&a[i]),edg[i].clear(); for(int i=2;i<=n;i++){ int v; scanf("%d",&v); edg[v].pb(i); } dfs(1,0); for(int i=1;i<=n;i++)root[i]=trie.insert(root[i-1],a[id[i]]); int l,r,x,u; while(m--){ scanf("%d%d",&u,&x); l=st[u];r=ed[u]; printf("%d\n",trie.query(root[l-1],root[r],x)); } } return 0; }
2017廣西邀請賽 Query on A Tree (可持續化字典樹)