• poj2761Feed the dogs(划分树-区间K值)


    链接

    这树着实不好理解啊

    讲解http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html

    对于找K值 右区间的确定不是太理解。。先当模板贴着吧

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 using namespace std;
     7 #define N 100010
     8 int tree[20][N],sum[20][N];//每层的数  及每层截止到i会放进左子树的个数
     9 int cu[N],xu[N];//原数据 及排序后的数据
    10 void build(int c,int l,int r)
    11 {
    12     int i,m = (l+r)>>1;
    13     int o = m-l+1,rp = m+1,lp = l;
    14     for(i = l ; i <= m ; i++)//左子树中与xu[m]相同的个数
    15     if(xu[i]<xu[m])
    16     o--;
    17     for(i = l ; i <= r ; i++)
    18     {
    19         if(i==l)
    20         sum[c][i] = 0;
    21         else
    22         sum[c][i] = sum[c][i-1];//维护一下 到I为止被分配到左子树中的个数 
    23         if(tree[c][i]==xu[m])
    24         {
    25             if(o)
    26             {
    27                 sum[c][i]++;
    28                 o--;
    29                 tree[c+1][lp++] = xu[m];//分配到左子树中
    30             }
    31             else
    32             tree[c+1][rp++] = tree[c][i];
    33         }
    34         else if(tree[c][i]<xu[m])
    35         {
    36             sum[c][i]++;
    37             tree[c+1][lp++] = tree[c][i];
    38         }
    39         else
    40         tree[c+1][rp++] = tree[c][i];//分配到右子树中
    41     }
    42     if(l==r) return ;
    43     build(c+1,l,m);
    44     build(c+1,m+1,r);
    45 }
    46 int query(int a,int b,int k,int c,int l,int r)
    47 {
    48     if(l==r)
    49     {
    50         return tree[c][l];
    51     }
    52     int m = (l+r)>>1;
    53     int s,ss;
    54     if(a==l)//这里特殊处理一下 sum没初始化 不然不处理应该也可以
    55     {
    56         s = 0;
    57         ss = sum[c][b];
    58     }
    59     else
    60     {
    61         s = sum[c][a-1];
    62         ss = sum[c][b]-s;
    63     }
    64     if(k<=ss)
    65     {
    66         return query(l+s,l+s+ss-1,k,c+1,l,m);
    67     }
    68     else
    69     return query(m-l+1+a-s,m-l+1+b-s-ss,k-ss,c+1,m+1,r);
    70 
    71 }
    72 int main()
    73 {
    74     int i,n,m;
    75     while(scanf("%d%d",&n,&m)!=EOF)
    76     {
    77         for(i = 1 ; i <= n ; i++)
    78         {
    79             scanf("%d",&cu[i]);
    80             tree[0][i] = cu[i];
    81             xu[i] = cu[i];
    82         }
    83         sort(xu+1,xu+n+1);
    84         build(0,1,n);
    85         while(m--)
    86         {
    87             int a,b,c;
    88             scanf("%d%d%d",&a,&b,&c);
    89             int ans = query(a,b,c,0,1,n);
    90             printf("%d
    ",ans);
    91         }
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    JAVA基础知识|HTTP协议-两个特性
    JAVA基础知识|TCP/IP协议
    Spring Cloud|高可用的Eureka集群服务
    Hadoop环境搭建|第四篇:hive环境搭建
    C#中Func与Action的理解
    C# lambda表达式
    WPF ControlTemplate
    sublime text3插件安装及使用
    Dev Express之ImageComboBoxEdit,RepositoryItemImageComboBox使用方式
    SQL查询结果增加序列号
  • 原文地址:https://www.cnblogs.com/shangyu/p/3319979.html
Copyright © 2020-2023  润新知