zoukankan      html  css  js  c++  java
  • SPOJ COT2

    题目:

        

    Description

    You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight.

    We will ask you to perfrom the following operation:

    • u v : ask for how many different integers that represent the weight of nodes there are on the path from u to v.

    Input

    In the first line there are two integers N and M.(N<=40000,M<=100000)

    In the second line there are N integers.The ith integer denotes the weight of the ith node.

    In the next N-1 lines,each line contains two integers u v,which describes an edge (u,v).

    In the next M lines,each line contains two integers u v,which means an operation asking for how many different integers that represent the weight of nodes there are on the path from u to v.

    Output

    For each operation,print its result.

    Example

    Input:           
    8 5
    8 2 105 2 9 3 8 5 7 7 1 2 1 3 1 4 3 5 3 6 3 7 4 8
    2 5
    7 8
    Output: 4
    <p>You are given a tree with <strong>N</strong> nodes.The tree nodes are numbered from <strong>1</strong> to <strong>N</strong>.Each node has an integer weight.</p>
    <p>We will ask you to perfrom the following operation:</p>
    <ul>
    <li><strong>u v k</strong> : ask for the kth minimum weight on the path from node <strong>u</strong> to node <strong>v</strong></li>
    </ul>
    <p> </p>
    <h3>Input</h3>
    <p>In the first line there are two integers <strong>N</strong> and <strong>M</strong>.(<strong>N,M</strong><=100000)</p>
    <p>In the second line there are <strong>N</strong> integers.The ith integer denotes the weight of the ith node.</p>
    <p>In the next <strong>N-1</strong> lines,each line contains two integers <strong>u</strong> <strong>v</strong>,which describes an edge (<strong>u</strong>,<strong>v</strong>).</p>
    <p>In the next <strong>M</strong> lines,each line contains three integers <strong>u</strong> <strong>v</strong> <strong>k</strong>,which means an operation asking for the kth minimum weight on the path from node <strong>u</strong> to node <strong>v</strong>.</p>
    <h3>Output</h3>
    <p>For each operation,print its result.</p>
    <h3>Example</h3>
    <pre><strong>Input:</strong>
    <div id="_mcePaste" style="position: absolute; left: -10000px; top: 320px; 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">8 5</div>8 5
    105 2 9 3 8 5 7 7
    1 2        
    1 3
    1 4
    3 5
    3 6
    3 7
    4 8<br />2 5 1<br />2 5 2<br />2 5 3<br />2 5 4<br />7 8 2 </pre>
    <pre><strong>Output:</strong>
    2<br />8<br />9<br />105<br />7 </pre>

    网上大概看到两种解法,一种是:http://blog.csdn.net/kuribohg/article/details/41458639 

                                            用xor 思想求得

    再一种就是这种直接求得:http://blog.csdn.net/u013598409/article/details/44943851 

    我说第二种:

    先ORZ 这位博主的代码 :

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 const int N=40001;
      9 const int M=161121;
     10 const int K=16;
     11 
     12 struct R
     13 {
     14     int d,id;
     15 }rk[N];
     16 int n,m,w[N];
     17 struct G
     18 {
     19     int v,nxt;
     20 }map[N<<1];
     21 int tot,hd[N];
     22 int in[N],out[N],lst[N<<1],num;
     23 int pre[K+2][N],dep[N];
     24 struct Q
     25 {
     26     int l,r,anc,id;
     27 }q[M];
     28 int v[N],unit,res,l,r,has[N],ans[M];    //注意ans的数据范围,为询问的个数
     29 
     30 inline void ins(int u,int v)
     31 {
     32     map[++tot].v=v;
     33     map[tot].nxt=hd[u];
     34     hd[u]=tot;
     35 }
     36 
     37 void DFS(int now,int high)
     38 {
     39     dep[now]=high;
     40     in[now]=++num;
     41     lst[num]=now;
     42 
     43     for (int k=hd[now];k;k=map[k].nxt)
     44         if (!dep[map[k].v])
     45         {
     46             DFS(map[k].v,high+1);
     47             pre[0][map[k].v]=now;
     48         }
     49 
     50     out[now]=++num;
     51     lst[num]=now;
     52 }
     53 
     54 inline int cmp1(R a,R b)
     55 {
     56     return a.d<b.d;
     57 }
     58 
     59 void init(void)
     60 {
     61     scanf("%d%d",&n,&m);
     62     for (int i=1;i<=n;i++) scanf("%d",&w[i]);
     63 
     64     int tmp,cnt;
     65     for (int i=1;i<=n;i++) rk[i].d=w[i],rk[i].id=i;
     66     sort(rk+1,rk+n+1,cmp1);
     67     tmp=rk[1].d,w[rk[1].id]=cnt=1;
     68     for (int i=2;i<=n;i++)
     69     {
     70         if (tmp^rk[i].d) tmp=rk[i].d,cnt++;
     71         w[rk[i].id]=cnt;
     72     }
     73 
     74     int x,y;
     75     for (int i=1;i<n;i++)
     76     {
     77         scanf("%d%d",&x,&y);
     78         ins(x,y),ins(y,x);
     79     }
     80 
     81     pre[0][1]=1;
     82     DFS(1,1);
     83 
     84     for (int i=1;i<=K;i++)
     85         for (int j=1;j<=n;j++)
     86             pre[i][j]=pre[i-1][pre[i-1][j]];
     87 }
     88 
     89 inline int cmp(Q a,Q b)
     90 {
     91     return a.l/unit!=b.l/unit?a.l/unit<b.l/unit:a.r<b.r;
     92 }
     93 
     94 inline int min(int i,int j)
     95 {
     96     return i<j?i:j;
     97 }
     98 
     99 inline int max(int i,int j)
    100 {
    101     return i>j?i:j;
    102 }
    103 
    104 inline int LCA(int x,int y)
    105 {
    106     if (dep[x]>dep[y]) x^=y^=x^=y;
    107     for (int i=K;i+1;i--)
    108         if (dep[y]-dep[x]>=1<<i) y=pre[i][y];
    109     if (x==y) return x;                            //注意特判x=y时的LCA就是x=y
    110     for (int i=K;i+1;i--)
    111         if (pre[i][x]^pre[i][y])
    112             x=pre[i][x],y=pre[i][y];
    113     return pre[0][x];
    114 }
    115 
    116 inline void solve(int i)        //"有无"时的写法
    117 {
    118     if (has[lst[i]])
    119     {
    120         v[w[lst[i]]]--;
    121         if (!v[w[lst[i]]]) res--;
    122         has[lst[i]]=0;
    123     }
    124     else
    125     {
    126         if (!v[w[lst[i]]]) res++;
    127         v[w[lst[i]]]++;
    128         has[lst[i]]=1;
    129     }
    130 }
    131 
    132 void work(void)
    133 {
    134     int x,y;
    135     unit=(int)sqrt(num);            //num instead of n
    136     for (int i=1;i<=m;i++)
    137     {
    138         scanf("%d%d",&x,&y);
    139         q[i].id=i;
    140         if (x==y) q[i].anc=-1;
    141         else
    142         {
    143             q[i].anc=LCA(x,y);
    144             if (q[i].anc!=x&&q[i].anc!=y)
    145             {
    146                 q[i].l=min(out[x],out[y]);
    147                 q[i].r=max(in[x],in[y]);
    148             }
    149             else
    150             {
    151                 q[i].l=min(in[x],in[y]);
    152                 q[i].r=max(in[x],in[y]);
    153             }                                //(1)相同        (2)有1个为LCA:两个in    (3) 都不同:max(in)&&min(out)
    154         }
    155     }
    156     sort(q+1,q+m+1,cmp);        //注意用id弄到ans,不能直接输出
    157 
    158     l=1,r=0;
    159     for (int i=1;i<=m;i++)
    160         if (q[i].anc==-1) ans[q[i].id]=1;
    161         else
    162         {
    163             for (;l<q[i].l;l++) solve(l);
    164             for (;q[i].l<l;l--)    solve(l-1);
    165             for (;r<q[i].r;r++) solve(r+1);
    166             for (;q[i].r<r;r--) solve(r);
    167             if (lst[q[i].l]==q[i].anc||lst[q[i].r]==q[i].anc)    //注意加上lst
    168                 ans[q[i].id]=res;
    169             else
    170             {
    171                 solve(in[q[i].anc]);
    172                 ans[q[i].id]=res;
    173                 solve(in[q[i].anc]);
    174             }
    175         }
    176 
    177     for (int i=1;i<=m;i++) printf("%d ",ans[i]);
    178 }
    179 
    180 int main(void)
    181 {
    182     init();
    183     work();
    184 
    185     return 0;

    186 } 

  • 相关阅读:
    c#实现冒泡、快速、选择和插入排序算法
    数据库>SQL Server>循环游标读取例子
    《道德经》程序员版第二章
    跨域访问JQuery+.NET实现的一种思路,以及极简单Demo
    《道德经》程序员版第三章
    ASP.NET初级>传智播客.net>第十一季asp.net中级 文字总结(未完)
    <div>里包含<p>标签疑问
    互联网音乐赚钱模式
    JQuery调用WebService,以及JS把单斜杠转换成双斜杠
    《道德经》程序员版第一章
  • 原文地址:https://www.cnblogs.com/forgot93/p/4788311.html
Copyright © 2011-2022 走看看