学习:http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html

划分树的build:

划分树是分层构建的,在构建的t层时,我们可以得到第t层的num域,和分入左右孩子的元素

num域值该区间中从左到某个位置小于指定值的数的个数

查找可以看代码

 //Accepted    28504 KB    1422 ms
 //划分树
 #include <cstdio>
 #include <cstring>
 #include <iostream>
 #include <queue>
 #include <cmath>
 #include <algorithm>
 using namespace std;
 /**
   * This is a documentation comment block
   * 如果有一天你坚持不下去了,就想想你为什么走到这儿!
   * @authr songt
   */
 ;
 struct node
 {
     int val[imax_n];   //val
     int num[imax_n];   //num
     long long sum[imax_n];   //sum
 }f[];
 int a[imax_n];
 int sorted[imax_n];
 void build(int t,int l,int r)
 {
     if (l==r) return ;
     ;
     ;
     ;
     for (int i=l;i<=r;i++)
     {
         if (f[t].val[i]<sorted[mid])
         isame--;
     }
     int ln=l;
     ;
     for (int i=l;i<=r;i++)
     {
         if (i==l)
         {
             f[t].sum[i]=;
             f[t].num[i]=;
         }
         else
         {
             f[t].sum[i]=f[t].sum[i-];
             f[t].num[i]=f[t].num[i-];
         }

         if (f[t].val[i]<sorted[mid])
         {
             f[t].num[i]++;
             f[t].sum[i]+=f[t].val[i];
             f[t+].val[ln++]=f[t].val[i];
         }
         else if (f[t].val[i]>sorted[mid])
         {
             f[t+].val[rn++]=f[t].val[i];
         }
         else
         {
             if (same<isame)
             {
                 same++;
                 f[t].num[i]++;
                 f[t].sum[i]+=f[t].val[i];
                 f[t+].val[ln++]=f[t].val[i];
             }
             else
             {
                 f[t+].val[rn++]=f[t].val[i];
             }
         }
     }
     build(t+,l,mid);
     build(t+,mid+,r);
 }
 ;
 int query(int t,int l,int r,int a,int b,int k)
 {
     if (l==r) return f[t].val[l];
     int s,ss,b1,b2;
     ;
     long long tsum;
     if (a==l)
     {
         s=f[t].num[b];
         ss=;
         tsum=f[t].sum[b];
     }
     else
     {
         s=f[t].num[b]-f[t].num[a-];
         ss=f[t].num[a-];
         tsum=f[t].sum[b]-f[t].sum[a-];
     }
     if (s>=k)  //当前查找区间[a,b]里包含的小于t=sorted[(left+right)/2]的数大于k个,则当前区间第k大的数
     {          //被分到[l,r]的左孩子,区间更新为[left+num[a-1],left+num[b]-1],
         a=l+ss;    //left--a-1 中包含num[a-1]个比t小的数,则[a,b]区间比t小的数,一定在left+num[a-1]后面
         b=l+ss+s-;;   //left--b 中一共包含了num[b]个比t小的数,则[a,b]区间中比t小的数的最大位置在left+num[b]-1
         ,l,mid,a,b,k);
     }
     else
     {               //当前查找区间[a,b]中小于t=sorted[(left+right)/2]的数的个数小于k个,则当前区间第k大的数
         b1=a-l-ss;  //被分到[l,r]的右孩子,区间更新为[mid+1+a-1-left-num[a-1]+1,mid+1+b-left-sum[b]]
         b2=b-a+-s;  //即[mid+1+a-left-num[a-1],mid+1+b-left-sum[b]]
         a=mid+b1+;  //因为left--a-1 分入左孩子的个数为num[a-1],所以分入右孩子的个数为r1=a-1-left+1-num[a-1]
         b=mid+b1+b2; //映射在右区间的开始位置是:mid+1+r1-1=mid+1+a-left-num[a-1]
         sum+=tsum;   //left--b 分入左孩子的个数为num[b] ,分入右孩子的个数就是b-left+1-num[b]
         ,mid+,r,a,b,k-s);   //映射到右区间得:mid+1+b-left+1-num[b]-1=mid+1+b-left-num[b]
     }
 }
 int n,m;
 int x,y,k;
 void slove()
 {
     build(,,n);
     ;i<=m;i++)
     {
         scanf("%d%d%d",&x,&y,&k);
         ,,n,x,y,k);
         printf("%d\n",t);
     }
 }
 int main()
 {
     while (scanf("%d%d",&n,&m)!=EOF)
     {
         ;i<=n;i++)
         {
             scanf("%d",&a[i]);
             f[].val[i]=sorted[i]=a[i];
         }
         sort(sorted+,sorted+n+);
         slove();
     }
     ;
 }

poj2104 线段树 划分树的更多相关文章

  1. 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

    如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...

  2. POJ2104 k-th number 划分树

    又是不带修改的区间第k大,这次用的是一个不同的方法,划分树,划分树感觉上是模拟了快速排序的过程,依照pivot不断地往下划分,然后每一层多存一个toleft[i]数组,就可以知道在这一层里从0到i里有 ...

  3. poj2104&&poj2761 (主席树&&划分树)主席树静态区间第k大模板

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 43315   Accepted: 14296 Ca ...

  4. hdu3473 线段树 划分树

    //Accepted 28904 KB 781 ms //划分树 //所求x即为l,r区间排序后的中位数t //然后求出小于t的数的和sum1,这个可以用划分树做 //求出整个区间的和sum,可以用O ...

  5. POJ 题目2761 Feed the dogs(主席树||划分树)

    Feed the dogs Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 16860   Accepted: 5273 De ...

  6. POJ2104 K-th Number 划分树 模板题啊

    /*Source Code Problem: 2104 User: 96655 Memory: 14808K Time: 1282MS Language: G++ Result: Accepted S ...

  7. poj2104 K大数 划分树

    题意:给定一个数列,求一个区间的第K大数 模板题, 其中的newl, newr 有点不明白. #include <iostream> #include <algorithm> ...

  8. 初学划分树,小见解之!POJ-2104/HDU-2665

    划分树 本来是学主席树的,可怜我等巨弱观群巨博客难解fotle主席的思想精髓.于是学了一下划分树,嗯,花了一下午时间理解build(其实自己模拟一遍就通了),我很难理解为什么划分树会看不懂而能学会主席 ...

  9. 划分树 poj2104 hdu5249

    KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

随机推荐

  1. ActiveX控件(MFC篇)

    目录 第1章 VC++6.0创建控件    1 1.1 目标    1 1.1.1 方法    1 1.1.2 属性    1 1.1.3 事件    1 1.2 创建项目    2 1.3 项目结构 ...

  2. Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 排序、筛选、分页以及分组

    Sorting, filtering, paging, and grouping 7 of 8 people found this helpful By Tom Dykstra The Contoso ...

  3. Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 增、查、改、删操作

    Create, Read, Update, and Delete operations¶ 5 of 5 people found this helpful By Tom Dykstra The Con ...

  4. 使用委托(C# 编程指南)

    原文地址:https://msdn.microsoft.com/zh-cn/library/ms173172.aspx 委托是安全封装方法的类型,类似于 C 和 C++ 中的函数指针.  与 C 函数 ...

  5. spring来了-03-bean创建细节

    对象创建:单例/多例  [bean节点的属性scope] scope="singleton", 默认值,即默认是单例     [service/dao/工具类] scope=&qu ...

  6. HTML5自学笔记[ 16 ]canvas绘图基础3

    canvas还提供提供了一些动态方法,使图像可以旋转.缩放和移动,与css3中的方法一样. 移动:translate(x,y),x和y为横竖方向的偏移量 旋转:rotate(弧度),弧度=角度*Mat ...

  7. C# EXCEL(.xls和.xlsx)导入到数据库

    C# EXCEL(.xls和.xlsx)导入到数据库  转(http://www.cnblogs.com/bart-cai/articles/2716555.html) 原理:1.判断是否是Excel ...

  8. Visual Studio中的快捷键

    我们在使用Visual Studio的时候,如用一些快捷键,就能减少我们键盘和鼠标来回切换的次数,从而提高我们编码的速度,在此跟大家分享一些经常Visual Studio中用到的快捷键 自动缩进:选中 ...

  9. urlrewrite伪静态 及多参数传递-附正则表达式语法 [轉]

    首先 加载 urlrewrite包 配置web.xml [list] [*] <error-page> [*]             <error-code>404</ ...

  10. Assert断言测试

    assert编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式.断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真.可以在 ...