hdu4417 划分树+二分

  1 //Accepted    14796 KB    453 ms
  2 //划分树
  3 //把查询的次数m打成n,也是醉了一晚上!!!
  4 //二分l--r区间第k大的数和h比较
  5 #include <cstdio>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <queue>
  9 #include <cmath>
 10 #include <algorithm>
 11 using namespace std;
 12 /**
 13   * This is a documentation comment block
 14   * 如果有一天你坚持不下去了,就想想你为什么走到这儿!
 15   * @authr songt
 16   */
 17 const int imax_n = 100005;
 18 struct node
 19 {
 20     int val[imax_n];
 21     int num[imax_n];
 22 }f[20];
 23 int a[imax_n];
 24 int sorted[imax_n];
 25 int n,m;
 26 void build(int t,int l,int r)
 27 {
 28     if (l==r) return ;
 29     int mid=(l+r)/2;
 30     int isame=mid-l+1;
 31     int same=0;
 32     for (int i=l;i<=r;i++)
 33     if (f[t].val[i]<sorted[mid]) isame--;
 34     int ln=l;
 35     int rn=mid+1;
 36     for (int i=l;i<=r;i++)
 37     {
 38         if (i==l)
 39         {
 40             f[t].num[i]=0;
 41         }
 42         else f[t].num[i]=f[t].num[i-1];
 43
 44         if (f[t].val[i]<sorted[mid])
 45         {
 46             f[t].num[i]++;
 47             f[t+1].val[ln++]=f[t].val[i];
 48         }
 49         else if (f[t].val[i]>sorted[mid])
 50         {
 51             f[t+1].val[rn++]=f[t].val[i];
 52         }
 53         else
 54         {
 55             if (isame>same)
 56             {
 57                 same++;
 58                 f[t].num[i]++;
 59                 f[t+1].val[ln++]=f[t].val[i];
 60             }
 61             else
 62             {
 63                 f[t+1].val[rn++]=f[t].val[i];
 64             }
 65         }
 66     }
 67     build(t+1,l,mid);
 68     build(t+1,mid+1,r);
 69 }
 70 int query(int t,int l,int r,int a,int b,int k)
 71 {
 72     if (l==r) return f[t].val[l];
 73     int mid=(l+r)/2;
 74     int s,ss;
 75     if (a==l)
 76     {
 77         ss=0;
 78         s=f[t].num[b];
 79     }
 80     else
 81     {
 82         ss=f[t].num[a-1];
 83         s=f[t].num[b]-ss;
 84     }
 85
 86     if (s>=k)
 87     {
 88         a=l+ss;
 89         b=l+ss+s-1;
 90         return query(t+1,l,mid,a,b,k);
 91     }
 92     else
 93     {
 94         int b1=a-l-ss;
 95         int b2=b-a+1-s;
 96         a=mid+1+b1;
 97         b=mid+b1+b2;
 98         return query(t+1,mid+1,r,a,b,k-s);
 99     }
100 }
101 int x,y,h;
102 void slove()
103 {
104     build(0,1,n);
105     for (int i=1;i<=m;i++)
106     {
107         scanf("%d%d%d",&x,&y,&h);
108         x++;
109         y++;
110         int l=1,r=y-x+1;
111         int mid=(l+r)/2;
112         int ans=0;
113         while (l<=r)
114         {
115             mid=(l+r)/2;
116             int t=query(0,1,n,x,y,mid);
117             //printf("pre :l=%d r=%d mid=%d t=%d\n",l,r,mid,t);
118             if (t>h) r=mid-1;
119             else
120             {
121                 ans=mid;
122                 l=mid+1;
123             }
124             //printf("l=%d r=%d t=%d\n",l,r,t);
125         }
126         printf("%d\n",ans);
127     }
128 }
129 int main()
130 {
131     int T;
132     int t=0;
133     scanf("%d",&T);
134     while (T--)
135     {
136         scanf("%d%d",&n,&m);
137         for (int i=1;i<=n;i++)
138         {
139             scanf("%d",&a[i]);
140             f[0].val[i]=sorted[i]=a[i];
141         }
142         sort(sorted+1,sorted+n+1);
143         printf("Case %d:\n",++t);
144         slove();
145     }
146     return 0;
147 }

时间: 2024-08-10 16:52:48

hdu4417 划分树+二分的相关文章

hdu4417(划分树)--二分

#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string.h> #include <queue> //hdu4417(划分树)--二分 #define N 100010 using namespace std; int sorted[N], p[20][N],

HDU 4417 划分树+二分

题意:有n个数,m个询问(l,r,k),问在区间[l,r] 有多少个数小于等于k. 划分树--查找区间第k大的数.... 利用划分树的性质,二分查找在区间[l,r]小于等于k的个数. 如果在区间第 i 大的数tmp>k,则往下找,如果tmp<k,往上找. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #incl

HDU-4417-Super Mario(划分树+二分)

Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss's castle as a l

sdut 2610:Boring Counting(第四届山东省省赛原题,划分树 + 二分)

Boring Counting Time Limit: 3000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence. Now you task is to answer a list of queries, for each quer

【划分树+二分】HDU 4417 Super Mario

第一次 耍划分树.. . 模板是找第k小的 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include &l

13年山东省赛 Boring Counting(离线树状数组or主席树+二分or划分树+二分)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 2224: Boring Counting Time Limit: 3 Sec  Memory Limit: 128 MB Description In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence.

K-th occurrence(后缀树组+划分树+ST表+RMQ+二分)

2019CCPC网络选拔赛1003 HDU6704 题目大意: T个测试样例.一个长度为N的字符串S,之后Q个[l,r,k],表示一个子串S[l,r],求出第k个该子串的下标.起始坐标为1.不存在输出-1. 数据范围:1≤T≤20,  1≤N≤105,  1≤Q≤105,  1≤l≤r≤N,  1≤k≤N,  |S|=N; 赛后补题.参考题解说后缀树组+划分树+ST表+二分. 比赛的时候只会后缀树组不会划分树,赛后仔细想,觉得后缀数组可以,然而并不,会TLE. 补提的时候先是采用后缀树组+划分树

poj 2104:K-th Number(划分树,经典题)

K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 35653   Accepted: 11382 Case Time Limit: 2000MS Description You are working for Macrohard company in data structures department. After failing your previous task about key inse

HDU 4417 Super Mario (划分树)(二分)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6077    Accepted Submission(s): 2645 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ab