zoukankan      html  css  js  c++  java
  • [BZOJ2588][SPOJ10628]Count on a tree

    题目大意:
      给定一棵$n(nleq100000)$个结点的带点权的树,有$m(mleq100000)$组询问,每次询问$u$到$v$的路径上第$k$小的权值。强制在线。

    思路:
      每个结点根据父结点建立可持久化权值线段树,查询时就查询$u+v-lca(u,v)-par[lca(u,v)]$的树即可。

      1 #include<list>
      2 #include<cstdio>
      3 #include<cctype>
      4 #include<algorithm>
      5 inline int getint() {
      6     register char ch;
      7     while(!isdigit(ch=getchar()));
      8     register int x=ch^'0';
      9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     10     return x;
     11 }
     12 const int N=100001,M=100000,logN=17;
     13 int w[N],tmp[N],dep[N],anc[N][logN];
     14 std::list<int> e[N];
     15 inline void add_edge(const int &u,const int &v) {
     16     e[u].push_back(v);
     17     e[v].push_back(u);
     18 }
     19 class FotileTree {
     20     private:
     21         struct Node {
     22             int val;
     23             Node *left,*right;
     24             Node() {}
     25             Node(const Node *const &p) {
     26                 *this=*p;
     27             }
     28         };
     29     public:
     30         Node *root[N];
     31         FotileTree() {
     32             root[0]=new Node;
     33             root[0]->left=root[0]->right=root[0];
     34         }
     35         Node *modify(const Node *const &last,const int &b,const int &e,const int &x) {
     36             Node *const p=new Node(last);
     37             p->val++;
     38             if(b==e) return p;
     39             const int mid=(b+e)>>1;
     40             if(x<=mid) p->left=modify(last->left,b,mid,x);
     41             if(x>mid) p->right=modify(last->right,mid+1,e,x);
     42             return p;
     43         }
     44         int query(const Node *const &p1,const Node *const &p2,const Node *const &p3,const Node *const &p4,const int &b,const int &e,const int &k) {
     45             if(b==e) return b;
     46             const int mid=(b+e)>>1;
     47             if(k<=p1->left->val+p2->left->val-p3->left->val-p4->left->val) return query(p1->left,p2->left,p3->left,p4->left,b,mid,k);
     48             return query(p1->right,p2->right,p3->right,p4->right,mid+1,e,k-(p1->left->val+p2->left->val-p3->left->val-p4->left->val));
     49         }
     50 };
     51 FotileTree t;
     52 inline int log2(const float &x) {
     53     return ((unsigned&)x>>23&255)-127;
     54 }
     55 void dfs(const int &x,const int &par) {
     56     t.root[x]=t.modify(t.root[par],1,tmp[0],w[x]);
     57     anc[x][0]=par;
     58     dep[x]=dep[par]+1;
     59     for(register int i=1;i<=log2(dep[x]);i++) {
     60         anc[x][i]=anc[anc[x][i-1]][i-1];
     61     }
     62     for(std::list<int>::iterator i=e[x].begin();i!=e[x].end();i++) {
     63         const int &y=*i;
     64         if(y==par) continue;
     65         dfs(y,x);
     66     }
     67 }
     68 inline int get_lca(int u,int v) {
     69     if(dep[u]<dep[v]) std::swap(u,v);
     70     while(dep[u]!=dep[v]) {
     71         u=anc[u][log2(dep[u]-dep[v])];
     72     }
     73     if(u==v) return u;
     74     for(register int i=log2(dep[u]);~i;i--) {
     75         if(anc[u][i]!=anc[v][i]) {
     76             u=anc[u][i];
     77             v=anc[v][i];
     78         }
     79     }
     80     return anc[u][0];
     81 }
     82 int main() {
     83     const int n=getint(),m=getint();
     84     for(register int i=1;i<=n;i++) {
     85         w[i]=tmp[i]=getint();
     86     }
     87     std::sort(&tmp[1],&tmp[n]+1);
     88     tmp[0]=std::unique(&tmp[1],&tmp[n]+1)-&tmp[1];
     89     for(register int i=1;i<=n;i++) {
     90         w[i]=std::lower_bound(&tmp[1],&tmp[tmp[0]]+1,w[i])-&tmp[0];
     91     }
     92     for(register int i=1;i<n;i++) {
     93         add_edge(getint(),getint());
     94     }
     95     dfs(1,0);
     96     for(register int i=0,ans=0;i<m;i++) {
     97         const int u=getint()^ans,v=getint(),k=getint(),lca=get_lca(u,v);
     98         if(i) putchar('
    ');
     99         printf("%d",ans=tmp[t.query(t.root[u],t.root[v],t.root[lca],t.root[anc[lca][0]],1,tmp[0],k)]);
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    (Ubuntu)Tensorflow object detection API——(2)运行已经训练好的模型
    tensorflow object detection API 验证时报No module named 'object_detection'
    (Ubuntu)Tensorflow object detection API——(1)环境搭建
    将图片数据保存为单个tfrecord文件
    线性系统和非线性系统
    一次 Druid 连接池泄露引发的血案!
    46 道阿里巴巴 Java 面试题,你会几道?
    想成为顶尖 Java 程序员?先过了下面这些问题!
    干掉PostMan!IDEA这款插件太实用了…
    网络常见的 9 大命令,非常实用!
  • 原文地址:https://www.cnblogs.com/skylee03/p/8461245.html
Copyright © 2011-2022 走看看