[luogu P2633] Count on a tree

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu P2633] Count on a tree相关的知识,希望对你有一定的参考价值。

[luogu P2633] Count on a tree

题目描述

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

输入输出格式

输入格式:

 

第一行两个整数N,M。

第二行有N个整数,其中第i个整数表示点i的权值。

后面N-1行每行两个整数(x,y),表示点x到点y有一条边。

最后M行每行两个整数(u,v,k),表示一组询问。

 

输出格式:

 

M行,表示每个询问的答案。

 

输入输出样例

输入样例#1: 复制
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2
输出样例#1: 复制
2
8
9
105
7

说明

HINT:

N,M<=100000

暴力自重。。。

来源:bzoj2588 Spoj10628.

本题数据为洛谷自造数据,使用CYaRon耗时5分钟完成数据制作。

主席树的变形,离散后,对于每个点u构造一棵新的主席树都建立在以fa[u][0]构造的主席树的基础之上。

其中,要按照dfs序来造,才能保证正确性。(用bfs序当然也可以咯)

然后询问两个点(x,y)时,根据主席树可加减的性质,只要在tree[x]+tree[y]-tree[lca(x,y)]-tree[fa[lca(x,y)]]这棵树上查询就可以了。

注意强制在线。

code:

技术分享图片
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <tr1/unordered_map>
  5 #define ms(a,x) memset(a,x,sizeof a)
  6 using namespace std;
  7 void OJ() {
  8     #ifndef ONLINE_JUDGE
  9         freopen("in.txt","r",stdin);
 10         freopen("out.txt","w",stdout);
 11     #endif
 12 }
 13 
 14 namespace fastIO {
 15     #define gec(c) getchar(c)
 16     #define puc(c) putchar(c)
 17     char ch;
 18     inline int read() {
 19         int x=0,f=1; ch=getchar();
 20         while (ch<0||ch>9) {
 21             if (ch==-) f=-f;
 22             ch=gec();
 23         }
 24         while (ch>=0&&ch<=9) {
 25             x=(x<<3)+(x<<1)+ch-0;
 26             ch=getchar();
 27         }
 28         return x*f;
 29     }
 30     int ttt,nnn[20];
 31     template <class T> inline void write(T x) {
 32         if (x==0) {
 33             puc(0); return;
 34         }
 35         if (x<0) x=-x,puc(-);
 36         for (ttt=0; x; x/=10) nnn[++ttt]=x%10;
 37         for (; ttt; --ttt) puc(nnn[ttt]+48);
 38     }
 39     inline void newline() {
 40         puc(\n);
 41     }
 42 } using namespace fastIO;
 43 
 44 const int N=100005;
 45 int n,m,cnt,b[N];
 46 int tot,lnk[N],nxt[N<<1],son[N<<1];
 47 int dep[N],fa[N][20],dfn[N],rel[N],clo;
 48 tr1::unordered_map <int,int> ref;
 49 struct data {
 50     int x,i;
 51 } a[N];
 52 inline bool cmp_x (const data &u,const data &v) {
 53     return u.x<v.x;
 54 }
 55 inline bool cmp_i (const data &u,const data &v) {
 56     return u.i<v.i;
 57 }
 58 struct node {
 59     node* l,* r; int v;
 60     node () {
 61         l=r=0,v=0;
 62     }
 63 } *r[N];
 64 #define M ((l)+(r)>>1)
 65 inline void setup (node* &c,int l,int r) {
 66     c=new node();
 67     if (l==r) return;
 68     setup(c->l,l,M),setup(c->r,M+1,r);
 69 }
 70 inline void insert (node* &c,int l,int r,int x,node* his) {
 71     c=new node();
 72     c->l=his->l,c->r=his->r,c->v=his->v+1;
 73     if (l==r) return;
 74     if (x<=M) insert(c->l,l,M,x,his->l);
 75     else insert(c->r,M+1,r,x,his->r);
 76 }
 77 inline int reply (node* x,node* y,node* z,node* o,int l,int r,int k,int v=0) {
 78     if (l==r) return b[l];
 79     v+=x->l->v,v+=y->l->v;
 80     v-=z->l->v,v-=o->l->v;
 81     if (k<=v) return reply(x->l,y->l,z->l,o->l,l,M,k);
 82     else return reply(x->r,y->r,z->r,o->r,M+1,r,k-v);
 83 }
 84 void add (int x,int y) {
 85     nxt[++tot]=lnk[x],lnk[x]=tot,son[tot]=y;
 86 }
 87 void dfs (int x,int p) {
 88     dep[x]=dep[p]+1,fa[x][0]=p,rel[dfn[x]=++clo]=x;
 89     for (int j=1; j<=18; ++j) fa[x][j]=fa[fa[x][j-1]][j-1];
 90     for (int j=lnk[x]; j; j=nxt[j]) {
 91         if (son[j]!=p) dfs(son[j],x);
 92     }
 93 }
 94 int lca (int x,int y) {
 95     if (dep[x]<dep[y]) swap(x,y);
 96     if (y==1) return 1;
 97     int dif=dep[x]-dep[y];
 98     for (int j=18; ~j; --j)
 99         if (dif&(1<<j)) x=fa[x][j];
100     if (x==y) return x;
101     for (int j=18; ~j; --j)
102         if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
103     return fa[x][0];
104 }
105 int main() {
106     OJ(); int x,y,z,o,k,lastans=0;
107     n=read(),m=read();
108     for (int i=1; i<=n; ++i) a[i].x=read();
109     for (int i=1; i<n; ++i) {
110         x=read(),y=read();
111         add(x,y),add(y,x);
112     }
113     dep[0]=0,dfn[0]=0,dfs(1,0);
114     for (int i=1; i<=n; ++i) a[i].i=dfn[i];
115     sort(a+1,a+1+n,cmp_x);
116     b[cnt=ref[a[1].x]=1]=a[1].x;
117     for (int i=2; i<=n; i++)
118         if (a[i].x!=a[i-1].x) b[ref[a[i].x]=++cnt]=a[i].x;
119     sort(a+1,a+1+n,cmp_i);
120     setup(r[0],1,cnt);
121     for (int i=1; i<=n; ++i) insert(r[i],1,cnt,ref[a[i].x],r[dfn[fa[rel[i]][0]]]);
122     for (int i=1; i<=m; ++i) {
123         x=read(),x^=lastans,y=read(),z=lca(x,y),o=fa[z][0],k=read();
124         x=dfn[x],y=dfn[y],z=dfn[z],o=dfn[o];
125         write(lastans=reply(r[x],r[y],r[z],r[o],1,cnt,k));
126         if (i^m) newline();
127     }
128     return 0;
129 }
View Code

以上是关于[luogu P2633] Count on a tree的主要内容,如果未能解决你的问题,请参考以下文章

P2633 Count on a tree

洛谷P2633 Count on a tree

P2633 Count on a tree(主席树)

P2633 Count on a tree 树上主席树

「luogu2633」Count on a tree

[SPOJ10707]Count on a tree II