区间更新,区间查询
区间更新用的是差分的做法实现的,理论时间复杂度应该是最快的?
不明白为什么有大佬能跑到几百ms,好像用的是整体二分。。。

详解以后有时间单独贴,理解起来不是很容易

差分做法:

#include<bits/stdc++.h>
#define ls ls_[i]
#define rs rs_[i]
#define mid (l+r)/2
using namespace std;
typedef long long ll;const int NN=100100;
ll n,m,k,x,y,z,q,W,T,N,S,op,cnt,tmp,dst,cas,sum,val,tot,idx,test;ll c[NN*40],d[NN*40];
int ls_[NN*40],rs_[NN*40];
int rot[NN],now_rotx[NN],now_roty[NN];void update(int l,int r,int pos,int val,int x,int &i){if(!i) i=++tot;c[i]+=val;d[i]+=val*x;if(l==r) return ;if(mid>=pos) update(l,mid,pos,val,x,ls);else update(mid+1,r,pos,val,x,rs);
}#define rx now_rotx[i]
#define ry now_roty[i]int main(){ios::sync_with_stdio(false);N=NN;cin>>n>>m;while(m--){cin>>op>>x>>y>>k;if(op==1){y++;for(int j=x;j<=n;j+=j&-j)update(0,N,k,1,x-1,rot[j]);for(int j=y;j<=n;j+=j&-j)update(0,N,k,-1,y-1,rot[j]);}else{int l=0,r=N;x--;for(int i=y;i;i-=i&-i) ry=rot[i];for(int i=x;i;i-=i&-i) rx=rot[i];//查询的非递归写法,递归式的我没想到该怎么写//因为树状数组节点的有序性决定它只适合做外壳//也许记录每个lowbit位置存前向星能放进内层?可以一试while(l!=r){ll c_rs=0;for(int i=y;i;i-=i&-i){c_rs+=c[rs_[ry]]*y;c_rs-=d[rs_[ry]];}for(int i=x;i;i-=i&-i){c_rs-=c[rs_[rx]]*x;c_rs+=d[rs_[rx]];}if(c_rs>=k){l=mid+1;for(int i=y;i;i-=i&-i) ry=rs_[ry];for(int i=x;i;i-=i&-i) rx=rs_[rx];}else{r=mid;k-=c_rs;for(int i=y;i;i-=i&-i) ry=ls_[ry];for(int i=x;i;i-=i&-i) rx=ls_[rx];}}cout<<l<<endl;}}
}

lazy数组做法(权值线段树做外壳):

#include<bits/stdc++.h>
#define mid (l+r)/2
using namespace std;typedef long long ll;
ll n,m,k,x,y,z,q,W,T,N,S,op,cnt,tmp,dst,cas,sum,val,tot,idx,test;const int NN=50100;
int rot[NN*4];
int ls_[NN*320],rs_[NN*320],c[NN*320],lazy[NN*320];void push_down(int ,int ,int );
void update(int ,int ,int ,int ,int& );
ll get_sum(int ,int ,int ,int ,int );
void update(int ,int ,int ,int ,int ,int );
ll get_kth(int ,int ,int ,int ,int ,int );inline int read() {int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;for(;isdigit(ch);x=(x<<3)+(x<<1)+(ch^48),ch=getchar());return x*f;
}int main(){n=read();m=read();N=NN;for(int i=1;i<=m;i++){op=read();x=read();y=read();k=read();if(op==1) update(0,N,k,x,y,1);else printf("%d\n",get_kth(0,N,k,x,y,1));}
}#define ls ls_[i]
#define rs rs_[i]
void push_down(int l,int r,int i){if(ls==0) ls=++tot;if(rs==0) rs=++tot;lazy[ls]+=lazy[i];lazy[rs]+=lazy[i];c[ls]+=lazy[i]*(mid-l+1);c[rs]+=lazy[i]*(r-mid);lazy[i]=0;
}void update(int l,int r,int L,int R,int &i){if(i==0) i=++tot;if(L<=l&&r<=R){lazy[i]++;c[i]+=r-l+1;return ;}if(lazy[i]) push_down(l,r,i);if(mid>=L) update(l,mid,L,R,ls);if(mid<R) update(mid+1,r,L,R,rs);c[i]=c[ls]+c[rs];
}ll get_sum(int l,int r,int L,int R,int i){if(i==0) return 0;if(L<=l&&r<=R) return c[i];if(lazy[i]) push_down(l,r,i);ll sum=0;if(mid>=L) sum+=get_sum(l,mid,L,R,ls);if(mid<R) sum+=get_sum(mid+1,r,L,R,rs);return sum;
}
#undef ls
#undef rs#define ls i<<1
#define rs i<<1|1
void update(int l,int r,int pos,int L,int R,int i){update(0,N,L,R,rot[i]);if(l==r) return ;if(mid>=pos) update(l,mid,pos,L,R,ls);else update(mid+1,r,pos,L,R,rs);
}ll get_kth(int l,int r,int k,int L,int R,int i){if(l==r) return l;ll r_ls=get_sum(0,N,L,R,rot[rs]);if(r_ls>=k) return get_kth(mid+1,r,k,L,R,rs);return get_kth(l,mid,k-r_ls,L,R,ls);
}

P3332 [ZJOI2013]K大数查询相关推荐

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

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

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

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

  3. P3332 [ZJOI2013]K大数查询 - 整体二分-区间修改

    题目链接:https://www.luogu.com.cn/problem/P3332 思路:我们区间修改用一个线段树维护就可以了. #include <bits/stdc++.h> us ...

  4. P3332 [ZJOI2013]K大数查询【整体二分】或【树套树】

    传送门 给定一个长度为NNN的可重集合 支持修改,离线 求区间可重集合的并集第K大 这里介绍两种方法[树套树]和 [整体二分] 这里还有个单点修改,有点类似的 P2617 Dynamic Rankin ...

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

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

  6. bzoj3110 [Zjoi2013]K大数查询

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

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

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

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

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

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

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

  10. bzoj3110: [Zjoi2013]K大数查询 【树套树,标记永久化】

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

最新文章

  1. shell中的执行流控制
  2. c语言函数指针的理解与使用(学习)
  3. 【Scratch】青少年蓝桥杯_每日一题_6.17_奇偶数
  4. BZOJ3930-莫比乌斯反演+杜教筛
  5. 异常作业2(2018.08.22)
  6. python是最好的语言 永远二十岁_“Python才是世界上最好的语言”
  7. Linux之虚拟机配置双网卡
  8. PCL Lesson6:Eigen基础
  9. java.lang.ClassNotFoundException: com.mysql.jdbc.Driver,网页一直处于加载中,servlet+html+js+css项目难题解决
  10. spring boot 2使用Mybatis多表关联查询
  11. OpenGl读取导入3D模型并且添加鼠标移动旋转显示
  12. ios 判断打开相机权限_ios 判断是否有权限访问相机,相册,定位
  13. linux系统windows模拟器下载,Linux开源模拟器Wine 0.9.54版下载
  14. 计算机毕业设计Java-超市会员积分管理系统
  15. 【线性代数之二】矩阵与行列式
  16. UOJ【UR #12】实验室外的攻防战 题解
  17. Unity实现隐藏鼠标功能
  18. 100 道 Linux 常见面试题,慢慢读~
  19. 大长今》及主题歌五种版本欣赏
  20. 跳跳虎辅助免费体验版

热门文章

  1. 扫描无法传送到计算机,文件无法从复印机扫描到电脑?可能是以下操作您没有注意到...
  2. instanceof和containsKey以及claims.getExpiration()以及expiration.before()的用法
  3. Jmeter刷csdn博客访问量
  4. 浅析资产配置的几种方法
  5. 机器人基础原理1_2——机器人分类与常见坐标系
  6. 智能合约漏洞检测工具mythril使用
  7. 直接收藏-超级好用的国内色彩搭配网站
  8. JS编写华氏度转摄氏度
  9. 关于音频情感分类的随笔(4)
  10. 稻盛和夫《活法》读书笔记