洛谷 2633 BZOJ 2588 Spoj 10628. Count on a tree

【题解】

  蜜汁强制在线。。。

  每个点开一个从它到根的可持久化权值线段树。查询的时候利用差分的思想在树上左右横跳就好了。

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define N 100010
 4 #define rg register
 5 #define ls (a[u].l)
 6 #define rs (a[u].r)
 7 using namespace std;
 8 int n,n2,m,tot,root[N],last[N],dep[N],top[N],hvy[N],fa[N],size[N],val[N],b[N];
 9 struct tree{
10     int sum,l,r;
11 }a[N*80];
12 struct edge{
13     int to,pre;
14 }e[N<<1];
15 inline int read(){
16     int k=0,f=1; char c=getchar();
17     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
18     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
19     return k*f;
20 }
21 inline int qlca(int x,int y){
22     int f1=top[x],f2=top[y];
23     while(f1!=f2){
24         if(dep[f1]<dep[f2]) swap(x,y),swap(f1,f2);
25         x=fa[f1]; f1=top[x];
26     }
27     return dep[x]<dep[y]?x:y;
28 }
29 void update(int &u,int l,int r,int pos){
30     a[++tot]=a[u]; a[u=tot].sum++;
31     if(l==r) return;
32     int mid=(l+r)>>1;
33     if(pos<=mid) update(ls,l,mid,pos);
34     else update(rs,mid+1,r,pos);
35 }
36 int query(int u,int v,int lca,int f,int l,int r,int k){
37     if(l==r) return l;
38     int tmp=a[ls].sum+a[a[v].l].sum-a[a[lca].l].sum-a[a[f].l].sum,mid=(l+r)>>1;
39     return k<=tmp?query(ls,a[v].l,a[lca].l,a[f].l,l,mid,k):query(rs,a[v].r,a[lca].r,a[f].r,mid+1,r,k-tmp);
40 }
41 void dfs1(int x){
42     size[x]=1; dep[x]=dep[fa[x]]+1;
43     root[x]=root[fa[x]]; update(root[x],1,n2,val[x]);
44     for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa[x]){
45         fa[to]=x; dfs1(to);
46         size[x]+=size[to];
47         if(size[to]>size[hvy[x]]) hvy[x]=to;
48     }
49 }
50 void dfs2(int x,int tp){
51     top[x]=tp;
52     if(hvy[x]) dfs2(hvy[x],tp);
53     for(rg int i=last[x],to;i;i=e[i].pre)
54         if((to=e[i].to)!=fa[x]&&to!=hvy[x]) dfs2(to,to);
55 }
56 int main(){
57     n=read(); m=read();
58     for(rg int i=1;i<=n;i++) val[i]=b[i]=read();
59     sort(b+1,b+1+n); n2=unique(b+1,b+1+n)-b-1;
60     for(rg int i=1;i<=n;i++) val[i]=lower_bound(b+1,b+1+n2,val[i])-b;
61     for(rg int i=1;i<n;i++){
62         int u=read(),v=read();
63         e[++tot]=(edge){v,last[u]}; last[u]=tot;
64         e[++tot]=(edge){u,last[v]}; last[v]=tot;
65     }
66     tot=0; dfs1(1); dfs2(1,1);
67     int last=0;
68     while(m--){
69         int u=read()^last,v=read(),k=read(),l=qlca(u,v),f=fa[l];
70         printf("%d\n",last=b[query(root[u],root[v],root[l],root[f],1,n2,k)]);
71     }
72     return 0;
73 }
View Code

 

转载于:https://www.cnblogs.com/DriverLao/p/8796247.html

内容概要:该题库专为研究生入学考试计算机组成原理科目设计,涵盖名校考研真题、经典教材课后习题、章节题库和模拟试题四大核心模块。名校考研真题精选多所知名高校的计算机组成原理科目及计算机联考真题,并提供详尽解析,帮助考生把握考研命题趋势与难度。经典教材课后习题包括白中英《计算机组成原理》(第5版)和唐朔飞《计算机组成原理》(第2版)的全部课后习题解答,这两部教材被众多名校列为考研指定参考书目。章节题库精选代表性考题,注重基础知识与重难点内容,帮助考生全面掌握考试大纲要求的知识点。模拟试题依据历年考研真题命题规律和热门考点,精心编制两套全真模拟试题,并附标准答案,帮助考生检验学习成果,评估应试能力。 适用人群:计划参加研究生入学考试并报考计算机组成原理科目的考生,尤其是需要系统复习和强化训练的学生。 使用场景及目标:①通过研读名校考研真题,考生可以准确把握考研命题趋势与难度,有效评估复习成效;②通过经典教材课后习题的练习,考生可以巩固基础知识,掌握解题技巧;③通过章节题库的系统练习,考生可以全面掌握考试大纲要求的各个知识点,为备考打下坚实基础;④通过模拟试题的测试,考生可以检验学习成果,评估应试能力,为正式考试做好充分准备。 其他说明:该题库不仅提供详细的题目解析,还涵盖了计算机组成原理的各个方面,包括计算机系统概述、数据表示与运算、存储器分层、指令系统、中央处理器、总线系统和输入输出系统等。考生在使用过程中应结合理论学习与实践操作,注重理解与应用,以提高应试能力和专业知识水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值