Description

有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

Input

第一行N,M
接下来M行,每行形如1 a b c或2 a b c

Output

输出每个询问的结果

Sample Input

2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3

Sample Output

1
2
1

HINT

【样例说明】

第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1

的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是

1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3

大的数是 1 。‍

N,M<=50000,N,M<=50000

a<=b<=N

1操作中abs(c)<=N

2操作中abs(c)<=Maxlongint

思路:

都是从浙江挂下来的考数据结构的歪风邪气←_←一看就知道是数据结构题啦=。=树套树。。我是写的树状数组套线段树。外层的树状数组记录有关数字的信息,内层的线段树记录有关位置的信息。也就是说我在[5,8]中加入了3这个数,就在外层的树状数组add_bit(3),然后在树状数组对应的节点上把[5,8]这个节点打上+1的标记。每次对于一个询问[L,R]中第k大的数,我们先转化为求第k小,然后二分答案,寻找在[l,r]中有多少比Mid小的数,收缩上下界就行了。p.s 网上说开树套树空间会爆,所以内层线段树要动态开点,我不知道要不要。。反正我是动态的。。不过跟静态的应该区别还是挺大的。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <string>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <queue>
  9 #include <stack>
 10 #include <map>
 11 #include <set>
 12 #include <list>
 13 #include <vector>
 14 #include <ctime>
 15 #include <functional>
 16 #define pritnf printf
 17 #define scafn scanf
 18 #define For(i,j,k) for(int i=(j);i<=(k);(i)++)
 19 #define Clear(a) memset(a,0,sizeof(a))
 20 using namespace std;
 21 typedef long long LL;
 22 typedef unsigned int Uint;
 23 const int INF=0x3fffffff;
 24 //==============struct declaration==============
 25 struct Node{
 26      Node *lc,*rc;
 27      long long sum,add;
 28      Node(){lc=rc=NULL;sum=add=0;}
 29 };
 30 //==============var declaration=================
 31 const int MAXN=80050;
 32 int n,m,L,R;
 33 long long sum[MAXN*2],addv[MAXN*2];
 34 Node *BitTree[MAXN];
 35 //==============function declaration============
 36 int lowbit(int x){return x&-x;}
 37 void add_bit(int x);
 38 void add_seg(Node *&o,int l,int r);
 39 long long  query_bit(int x);
 40 long long query_seg(Node *&i,int l,int r,long long add);
 41 void update(Node *&o,int l,int r);
 42 void add_num(int o,int l,int r);
 43 long long query_num(int o,int l,int r,long long add);
 44 //==============main code=======================
 45 int main()
 46 {
 47 #define FILE__
 48 #ifdef FILE__
 49     freopen("input","r",stdin);
 50     freopen("output","w",stdout);
 51 #endif
 52     scanf("%d%d",&n,&m);n++;
 53     for(int i=1;i<=n;i++) BitTree[i]=NULL;
 54     while (m--){
 55         int cmd,a,b;long long c;scanf("%d%d%d%lld",&cmd,&a,&b,&c);
 56         if (cmd==1){
 57              L=a;R=b;
 58              add_bit(c);add_num(1,1,n-1);
 59         }
 60         else if (cmd==2){
 61             int low=1,high=n-1,mid;
 62             L=a;R=b;
 63             long long Num_Exist=query_num(1,1,n-1,0);
 64             c=Num_Exist-c+1;
 65             while (low<high){
 66                 mid=(low+high)>>1;
 67                 long long tmp=query_bit(mid);
 68                 if (tmp<c)     low=mid+1;
 69                 if (tmp>=c)     high=mid;
 70             }
 71             printf("%d\n",low);
 72         }
 73     }
 74    return 0;
 75 }
 76 //================fuction code====================
 77 void add_bit(int x){
 78    while (x<=n){
 79        add_seg(BitTree[x],1,n-1);
 80        x+=lowbit(x);
 81    }
 82 }
 83 void add_seg(Node *&o,int l,int r){
 84     int m=(l+r)>>1;
 85     if (o==NULL)  o=new(Node);
 86     if (L<=l&&r<=R){
 87         o->add++;
 88         update(o,l,r);
 89         return;
 90     }
 91     if (m>=L)   add_seg(o->lc,l,m);
 92     if (m<R)    add_seg(o->rc,m+1,r);
 93     update(o,l,r);
 94 }
 95 void update(Node *&o,int l,int r){
 96     o->sum=0;
 97     if (o->lc!=NULL)    o->sum+=o->lc->sum;
 98     if (o->rc!=NULL)    o->sum+=o->rc->sum;
 99     o->sum+=(r-l+1)*o->add;
100 }
101 long long query_bit(int x){
102     long long res=0;
103     while (x>0){
104         res+=query_seg(BitTree[x],1,n-1,0);
105         x-=lowbit(x);
106     }
107     return res;
108 }
109 long long query_seg(Node *&o,int l,int r,long long add){
110     if (o==NULL)    return add*(min(r,R)-max(l,L)+1);
111     int m=(l+r)>>1;
112     if (L<=l&&r<=R)
113         return o->sum+(r-l+1)*add;
114     long long Left=0,Right=0;
115     if (m>=L)    Left=query_seg(o->lc,l,m,add+o->add);
116     if (m<R)    Right=query_seg(o->rc,m+1,r,add+o->add);
117     return Left+Right;
118 }
119 void add_num(int o,int l,int r){
120     if (L<=l&&r<=R){
121         addv[o]++;
122         sum[o]+=r-l+1;
123     }
124     else{
125         int lc=o*2,rc=o*2+1,m=(l+r)>>1;
126         if (m>=L)    add_num(lc,l,m);
127         if (m<R)    add_num(rc,m+1,r);
128         sum[o]=sum[lc]+sum[rc]+addv[o]*(r-l+1);
129     }
130 }
131 long long query_num(int o,int l,int r,long long add){
132     int lc=o*2,rc=o*2+1,m=(l+r)>>1;
133     if (L<=l&&r<=R)
134         return sum[o]+add*(r-l+1);
135     long long Left=0,Right=0;
136     if (m>=L)  Left=query_num(lc,l,m,add+addv[o]);
137     if (m<R)  Right=query_num(rc,m+1,r,add+addv[o]);
138     return Left+Right;
139 }

Prob_3110

转载于:https://www.cnblogs.com/Houjikan/p/4302662.html

【ZJOI2013】k大数查询 BZOJ 3110相关推荐

  1. bzoj 3110: [Zjoi2013]K大数查询(树套树)

    树套树: 本质:一棵树的每个节点套着另一棵树 通常时间复杂度:O(nlog²n) 空间复杂度:因为树的大小是nlogn,而每个节点又有一棵nlogn的树,所以最大空间复杂度为O(n²log²) 但事实 ...

  2. 3110: [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 https://lydsy.com/JudgeOnline/problem.php?id=3110 分析: 整体二分+线段树. 两种操作:区间加入一个数,区 ...

  3. bzoj3110 [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 10703  Solved: 3209 [Submit][ ...

  4. [BZOJ3110] [Zjoi2013]K大数查询

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 9208  Solved: 2737 [Submit][S ...

  5. 洛谷 P3332 [ZJOI2013]K大数查询 解题报告

    P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...

  6. BZOJ3110: [Zjoi2013]K大数查询

    BZOJ3110: [Zjoi2013]K大数查询 Description 有N个位置,M个操作. 操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如 ...

  7. P3332 [ZJOI2013]K大数查询(整体二分做法)

    P3332 [ZJOI2013]K大数查询 题意: 题解: 利用整体二分来做,这个题和P3834 [模板]可持久化线段树 2的区别在于本题的修改是区间修改,所以将里面的树状数组改成线段树就行,区间修改 ...

  8. bzoj:3110: [Zjoi2013]K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  9. [bzoj 3110] [ZJOI2013] K大数查询

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3110 题目: 有N个位置,M个操作.操作有两种,每次操作如果是: 1 a b c:表示 ...

最新文章

  1. 也说c#获取windows特殊路径
  2. WINCE下实现基于USB的camera
  3. 2018 Spring Team Contest B
  4. 最新:全球大型数据中心总数增至597个,是2015年数据中心数量的两倍
  5. java 面向对象的特性 抽象_java面向对象的四个特性
  6. [阅读笔记] Java 7 新特性
  7. 电脑技巧:盘点常用的Win组合快捷键
  8. android 代码获取屏幕图像,安卓获取屏幕以及获得像素点 ~ 大树洞
  9. python对文本数据进行采样_Python对wav文件的重采样实例
  10. 我:一个女孩从软件测试工程师到主管的成长
  11. ZooKeeper学习第八期——ZooKeeper伸缩性
  12. python中type与isinstance异同
  13. HashSet原理、TreeSet
  14. 3.9 JS制作登录验证码
  15. Triple Flips CodeForces - 1072E
  16. 我的CSDN博客十年
  17. 传统零售业务分析指标整理
  18. 网页编程设计常用的各类标签
  19. 两台Ubuntu18.04局域网共享文件夹,互相访问
  20. DPU网络开发SDK——DPDK(九)

热门文章

  1. C#命名规范 C#控件的缩写大全
  2. 删除数据 DataIntegrityViolationException: not-null property references a null or transient value解决...
  3. Nginx开启gzip压缩解决react打包文件过大
  4. VMware对虚拟机快照进行克隆
  5. 3.2 表达式的类别与类型
  6. 【laravel】同一代码段内,先更新数据,后查询修改的数据,查询结果错误的问题
  7. 【ORACLE】碎片整理
  8. node学习笔记--模块加载
  9. nginx相关的一些记录
  10. Asp.net2.0下的大文件上传服务器控件