数据结构(线段树):HDU 5649 DZY Loves Sorting

DZY Loves Sorting

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 294    Accepted Submission(s): 77

Problem Description

  DZY has a sequence a[1..n]. It is a permutation of integers 1∼n.
  Now he wants to perform two types of operations:
    0 l r: Sort a[l..r] in increasing order.
    1 l r: Sort a[l..r] in decreasing order.
  After doing all the operations, he will tell you a position k, and ask you the value of a[k].

Input

  First line contains t, denoting the number of testcases.
  t testcases follow. For each testcase:
  First line contains n,m. m is the number of operations.
  Second line contains n space-separated integers a[1],a[2],?,a[n], the initial sequence. We ensure that it is a permutation of 1∼n.
  Then m lines follow. In each line there are three integers opt,l,r to indicate an operation.
  Last line contains k.
  (1≤t≤50,1≤n,m≤100000,1≤k≤n,1≤l≤r≤n,opt∈{0,1}. Sum of n in all testcases does not exceed 150000. Sum of m in all testcases does not exceed 150000)

Output

  For each testcase, output one line - the value of a[k] after performing all m operations.

Sample Input

  1

  6 3

  1 6 2 5 3 4

  0 1 4

  1 3 6

  0 2 4

  3

Sample Output

  5

Hint

1 6 2 5 3 4 -> [1 2 5 6] 3 4 -> 1 2 [6 5 4 3] -> 1 [2 5 6] 4 3. At last a[3]=5.

  好题,考虑二分的话,维护的只是相对大小,题目就好做了。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=100010;
 6 int n,m,k;
 7 int tr[maxn<<2],mark[maxn<<2];
 8 int L[maxn],R[maxn],X[maxn],a[maxn];
 9
10 void Make_same(int x,int l,int r,int d){
11     tr[x]=(r-l+1)*d;
12     mark[x]=d;
13 }
14
15 void Push_down(int x,int l,int r){
16     if(mark[x]!=-1){
17         int mid=(l+r)>>1;
18         Make_same(x<<1,l,mid,mark[x]);
19         Make_same(x<<1|1,mid+1,r,mark[x]);
20         mark[x]=-1;
21     }
22 }
23
24 void Build(int x,int l,int r,int g){
25     mark[x]=-1;
26     if(l==r){
27         tr[x]=a[l]<=g?0:1;
28         return;
29     }
30     int mid=(l+r)>>1;
31     Build(x<<1,l,mid,g);
32     Build(x<<1|1,mid+1,r,g);
33     tr[x]=tr[x<<1]+tr[x<<1|1];
34 }
35
36 int Query(int x,int l,int r,int a,int b){
37     Push_down(x,l,r);
38     if(l>=a&&r<=b)return tr[x];
39     int mid=(l+r)>>1,ret=0;
40     if(mid>=a)ret=Query(x<<1,l,mid,a,b);
41     if(mid<b)ret+=Query(x<<1|1,mid+1,r,a,b);
42     return ret;
43 }
44
45 void Mark(int x,int l,int r,int a,int b,int d){
46     if(a>b)return;
47     if(l>=a&&r<=b){
48         Make_same(x,l,r,d);
49         return;
50     }
51     Push_down(x,l,r);
52     int mid=(l+r)>>1;
53     if(mid>=a)Mark(x<<1,l,mid,a,b,d);
54     if(mid<b)Mark(x<<1|1,mid+1,r,a,b,d);
55     tr[x]=tr[x<<1]+tr[x<<1|1];
56 }
57
58 bool Check(){
59     for(int i=1;i<=m;i++){
60         int sum=Query(1,1,n,L[i],R[i]);
61         if(X[i]){
62             Mark(1,1,n,L[i],L[i]+sum-1,1);
63             Mark(1,1,n,L[i]+sum,R[i],0);
64         }
65         else{
66             sum=R[i]-L[i]+1-sum;
67             Mark(1,1,n,L[i],L[i]+sum-1,0);
68             Mark(1,1,n,L[i]+sum,R[i],1);
69         }
70     }
71     return Query(1,1,n,k,k);
72 }
73
74 void Solve(){
75     int lo=1,hi=n;
76     while(lo<=hi){
77         int mid=(lo+hi)>>1;
78         Build(1,1,n,mid);
79         if(Check())lo=mid+1;
80         else hi=mid-1;
81     }
82     printf("%d\n",lo);
83     return;
84 }
85 int main(){
86     int T;
87     scanf("%d",&T);
88     while(T--){
89         scanf("%d%d",&n,&m);
90         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
91         for(int i=1;i<=m;i++)scanf("%d%d%d",&X[i],&L[i],&R[i]);
92         scanf("%d",&k);
93         Solve();
94     }
95     return 0;
96 }
时间: 2024-10-13 00:04:52

数据结构(线段树):HDU 5649 DZY Loves Sorting的相关文章

HDU 5649 DZY Loves Sorting(二分答案+线段树、线段树合并+线段树分割)

题意 一个 \(1\) 到 \(n\) 的全排列,\(m\) 种操作,每次将一段区间 \([l,r]\) 按升序或降序排列,求 \(m\) 次操作后的第 \(k\) 位. \(1 \leq n \leq 10^5\) 思路 两个 \(\log\) 的做法展现了二分答案的强大功能.首先二分枚举第 \(k\) 位的值,然后将小于等于它的数都变为 \(1\) ,大于它的数变为 \(0\) ,线段树可以实现对 \(01\) 序列快速的排序,按要求进行排序,然后如果第 \(k\) 位为 \(1\) 说明这

HDU 4902 Nice boat(数据结构-线段树)

Nice boat Problem Description There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and c

HDU 1394 Minimum Inversion Number (数据结构-线段树)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9514    Accepted Submission(s): 5860 Problem Description The inversion number of a given number sequence a1, a2, ..., an

Chapter 3. 数据结构 线段树

Chapter 3. 数据结构 线段树 Sylvia's I.单点修改,区间查询. 模板: //单点修改 区间求和 //1操作 单点修改//2操作 区间求和 #include<cstdio> #include<iostream> using namespace std; #define MAXN 500005 int sum[MAXN<<2]; int n,m; void PushUp(int rt){//求和 sum[rt]=sum[rt<<1]+sum[

hdu 5195 DZY Loves Topological Sorting 线段树+拓扑排序

DZY Loves Topological Sorting Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5195 Description A topological sort or topological ordering of a directed graph is a linear ordering of its vertices such that for ev

hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 52 Problem Description A topological sort or topological ordering of a directed

HDU 5195 DZY Loves Topological Sorting (拓扑排序+线段树)

题目地址:HDU 5195 简直受不了了..BC第二题都开始线段树+拓扑排序了... 这题很容易想到拓扑排序过程中贪心,但是贪心容易TLE,所以需要用数据结构去维护,我用的是线段树维护.每次找入度小于等于k的编号最大的点,这样就可以保证字典序一定是最大的. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorith

hdu.5195.DZY Loves Topological Sorting(topo排序 &amp;&amp; 贪心)

DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 866    Accepted Submission(s): 250 Problem Description A topological sort or topological ordering of a directed g

数据结构---线段树

线段树 转载请注明出处,谢谢!http://blog.csdn.net/metalseed/article/details/8039326  持续更新中···   一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,它基本能保持每个操作的复杂度为O(lgN)! 性质:父亲的区间是[a,b],(c=(a+b)/2)左儿子的区间是[a,c],右儿子的区间是[c+1,b],线段树