hdu5412CRB and Queries

动态修改求区间K大。

整体二分是一个神奇的东西: http://www.cnblogs.com/zig-zag/archive/2013/04/18/3027707.html

入门:

一般的主席树都挂了,而且又难写。

南神的分析:http://blog.csdn.net/hdu2014/article/details/47834431 ORZ

然后对着板子写了一份:

1 #include<iostream>

2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #define maxn 450000
  7 #define inf 2000000000
  8 typedef long long ll;
  9 
 10 using namespace std;
 11 struct query
 12 {
 13     int x,y,k,s,tp,cur;
 14 }q[maxn],q1[maxn],q2[maxn];
 15 int a[maxn],ans[maxn],tmp[maxn],t[maxn];
 16 int n,m,num,cnt;
 17 
 18 void add(int x,int y)
 19 {
 20     for (int i=x;i<=n;i+=i&(-i)) t[i]+=y;
 21 }
 22 int ask(int x)
 23 {
 24     int s=0;
 25     for (int i=x;i>0;i-=i&(-i)) s+=t[i];
 26     return s;
 27 }
 28 
 29 void divide(int head,int tail,int l,int r)
 30 {
 31     if (head>tail) return;
 32     if (l==r)
 33     {
 34         for (int i=head;i<=tail;i++)
 35             if (q[i].tp==3) ans[q[i].s]=l;
 36         return;
 37     }
 38     int mid=(l+r)>>1;
 39     for (int i=head;i<=tail;i++)
 40     {
 41         if (q[i].tp==1&&q[i].y<=mid) add(q[i].x,1);
 42         else
 43         if (q[i].tp==2&&q[i].y<=mid) add(q[i].x,-1);
 44         else
 45         if (q[i].tp==3) tmp[i]=ask(q[i].y)-ask(q[i].x-1);
 46     }
 47 
 48     for (int i=head;i<=tail;i++)
 49     {
 50         if (q[i].tp==1&&q[i].y<=mid) add(q[i].x,-1);
 51         else
 52         if (q[i].tp==2&&q[i].y<=mid) add(q[i].x,1);
 53     }
 54 
 55     int l1,l2;
 56     l1=l2=0;
 57     for (int i=head;i<=tail;i++)
 58     if (q[i].tp==3)
 59     {
 60        if (q[i].cur+tmp[i]>q[i].k-1) q1[++l1]=q[i];
 61        else
 62        {
 63            q[i].cur+=tmp[i];
 64            q2[++l2]=q[i];
 65        }
 66     }
 67     else
 68     {
 69         if (q[i].y<=mid) q1[++l1]=q[i];
 70         else q2[++l2]=q[i];
 71     }
 72 
 73     for (int i=1;i<=l1;i++) q[head+i-1]=q1[i];
 74     for (int i=1;i<=l2;i++) q[head+i+l1-1]=q2[i];
 75     divide(head,head+l1-1,l,mid);
 76     divide(head+l1,tail,mid+1,r);
 77 }
 78 
 79 int main()
 80 {
 81     while (scanf("%d",&n)!=EOF)
 82     {
 83         for (int i=0;i<=n;i++) t[i]=0;
 84         memset(q,0,sizeof(q));
 85         memset(q1,0,sizeof(q1));
 86         memset(q2,0,sizeof(q2));
 87 
 88         num=cnt=0;
 89         for (int i=1;i<=n;i++)
 90         {
 91             scanf("%d",&a[i]);
 92             q[++num].x=i,q[num].y=a[i];
 93             q[num].tp=1;q[num].s=0;
 94         }
 95         int ss,x,y,z;
 96         scanf("%d",&m);
 97         for (int i=1;i<=m;i++)
 98         {
 99             scanf("%d",&ss);
100             if (ss==2)
101             {
102                 scanf("%d%d%d",&x,&y,&z);
103                 q[++num].x=x,q[num].y=y,q[num].k=z;
104                 q[num].tp=3;q[num].s=++cnt;
105             }
106             else
107             {
108                 scanf("%d%d",&x,&y);
109                 q[++num].x=x;
110                 q[num].y=a[x];
111                 q[num].tp=2;q[num].s=0;
112                 q[++num].x=x,q[num].y=y;
113                 q[num].tp=1,q[num].s=0;
114                 a[x]=y;
115             }
116         }
117 
118         divide(1,num,0,inf);
119         for (int i=1;i<=cnt;i++)
120             printf("%d\n",ans[i]);
121     }
122     return 0;

123 }

2s左右。

时间: 2024-12-28 14:48:59

hdu5412CRB and Queries的相关文章

HDU4027 Can you answer these queries 线段树区间求和+剪枝

给了你n,然后n个数字在一个数组中,接下来m个询问,每个询问三个数字 t,x,y,若t==0,那么修改区间[x,y]的每一个值,变为原来每个位置上的数 开根号取整,若t==1,那么对区间[x,y]求和 由于n,m,很大,所以树状数组铁定超时,若直接用线段树来做区间修改,那么也是超时,这类题目没别的方法了,静心剪枝,发现题目给的数据范围为2^63,有没有发现,2^63开根号 绝对不需要开10次,就能到1,到1以后就不需要再开了,意思就是若有某个区间[x,y]每一个点的值都为1时,这一段区间事实上是

[CodeChef - GERALD07 ] Chef and Graph Queries

Read problems statements in Mandarin Chineseand Russian. Problem Statement Chef has a undirected graph G. This graph consists of N vertices and M edges. Each vertex of the graph has an unique index from 1 to N, also each edge of the graph has an uniq

Bitwise And Queries

Bitwise And Queries Time limit: 1500 msMemory limit: 128 MB You are given QQ queries of the form a\ b\ xa b x. Count the number of values yy such that a \leq y \leq ba≤y≤b and x\ \& \ y = xx & y=x, where we denote by \&& the bitwise and op

JavaScript根据CSS的Media Queries来判断浏览设备的方法

CSS 部分 首先随便新建一个用来做判断的类,然后通过 Media Queries 来对这个类的 z-index 属性赋予不同的值.这个类仅作为 JavaScript 读取使用,所以需要将其移出屏幕窗口,让浏览者不可见以免引起意外情况. 作为演示,下面代码设置了四种设备状态:桌面普通版.小屏幕桌面版.平板电脑版和手机版. /* default state */ .state-indicator { position: absolute; top: -999em; left: -999em; z-

lightoj Again Array Queries

1100 - Again Array Queries   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 MB Given an array with n integers, and you are given two indices i and j (i ≠ j) in the array. You have to find two integers in the range whose diffe

响应式web设计之CSS3 Media Queries

开始研究响应式web设计,CSS3 Media Queries是入门. Media Queries,其作用就是允许添加表达式用以确定媒体的环境情况,以此来应用不同的样式表.换句话说,其允许我们在不改变内容的情况下,改变页面的布局以精确适应不同的设备. 那么,Media Queries是如何工作的? 两种方式,一种是直接在link中判断设备的尺寸,然后引用不同的css文件: <link rel="stylesheet" type="text/css" href=

Medial Queries的另一用法:实现IE hack的方法

所谓Medial Queries就是媒体查询. 随着Responsive设计的流行,Medial Queries可算是越来越让人观注了.他可以让Web前端工程实现不同设备下的样式选择,让站点在不同的设备中实现不同的效果. 众所周知,有些时候为了实现IE下的某些效果与现代浏览器一致,我们不得不使用一些hack手段来实现目的.比如说使用“\0”,“\”和“\9”来仅让IE某些版本识别,而对于现代浏览器来说,他会直接无视这些代码.今天我想为大家介绍的是使用@media实现IE hack的方法. 仅IE

hdu 5412 CRB and Queries(线段树套笛卡尔树 - 动态区间第k大)

题目链接:hdu 5412 CRB and Queries 首先对所有出现过的值排序,建立线段树,每个线段树的节点是一棵笛卡尔树,笛卡尔树记录区间下标值. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define lson(x) (x<<1) #define rson(x) ((x<<

hdu4027 Can you answer these queries?

Problem Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of ou