树状数组套权值线段树

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string> #define E exit(0) using namespace std; #define LL long long #define gc getchar()
inline int read() {int x = ; char c = gc; while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc; return x;}
inline LL read_LL() {LL x = ; char c = gc; while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc; return x;}
#undef gc const int N = 5e4 + ;
const int Out = ; struct Node {int opt, l, r, k;} Ask[N];
int n, m;
int Num[N << ], totNum, A[N], Length; int Root[N];
int W[N * ], Lson[N * ], Rson[N * ]; int Add_root[N], Cut_root[N];
int Hjt_; namespace Seg { void Insert(int &rt, int l, int r, int x) {
if(!rt) rt = ++ Hjt_;
W[rt] ++;
if(l == r) return ;
int mid = (l + r) >> ;
if(x <= mid) Insert(Lson[rt], l, mid, x);
else Insert(Rson[rt], mid + , r, x);
} int Getrank(int l, int r, int k, int opt) {
if(l == r) {
if(opt == ) return ;
int s = ;
for(int i = ; i <= Add_root[]; i ++) s += W[Add_root[i]];
for(int i = ; i <= Cut_root[]; i ++) s -= W[Cut_root[i]];
return s;
}
int mid = (l + r) >> ;
if(k <= mid) {
for(int i = ; i <= Add_root[]; i ++) Add_root[i] = Lson[Add_root[i]];
for(int i = ; i <= Cut_root[]; i ++) Cut_root[i] = Lson[Cut_root[i]];
return Getrank(l, mid, k, opt);
} else {
int sum = ;
for(int i = ; i <= Add_root[]; i ++) {
sum += W[Lson[Add_root[i]]]; Add_root[i] = Rson[Add_root[i]];
}
for(int i = ; i <= Cut_root[]; i ++) {
sum -= W[Lson[Cut_root[i]]]; Cut_root[i] = Rson[Cut_root[i]];
}
int ret = sum + Getrank(mid + , r, k, opt);
return ret;
}
} int Getnum(int l, int r, int k) {
if(l == r) return l;
int mid = (l + r) >> ;
int sum = ;
for(int i = ; i <= Add_root[]; i ++) sum += W[Lson[Add_root[i]]];
for(int i = ; i <= Cut_root[]; i ++) sum -= W[Lson[Cut_root[i]]];
if(sum >= k) {
for(int i = ; i <= Add_root[]; i ++) Add_root[i] = Lson[Add_root[i]];
for(int i = ; i <= Cut_root[]; i ++) Cut_root[i] = Lson[Cut_root[i]];
Getnum(l, mid, k);
} else {
for(int i = ; i <= Add_root[]; i ++) Add_root[i] = Rson[Add_root[i]];
for(int i = ; i <= Cut_root[]; i ++) Cut_root[i] = Rson[Cut_root[i]];
Getnum(mid + , r, k - sum);
}
} void Poi_G(int l, int r, int x, int val) {
for(int i = ; i <= Cut_root[]; i ++) W[Cut_root[i]] += val;
if(l == r) return ;
int mid = (l + r) >> ;
if(x <= mid) {
for(int i = ; i <= Cut_root[]; i ++) {
if(Lson[Cut_root[i]] == ) Lson[Cut_root[i]] = ++ Hjt_;
Cut_root[i] = Lson[Cut_root[i]];
}
Poi_G(l, mid, x, val);
} else {
for(int i = ; i <= Cut_root[]; i ++) {
if(Rson[Cut_root[i]] == ) Rson[Cut_root[i]] = ++ Hjt_;
Cut_root[i] = Rson[Cut_root[i]];
}
Poi_G(mid + , r, x, val);
}
} int Asknum(int l, int r, int k) {
if(l == r) {
int sum = ;
for(int i = ; i <= Add_root[]; i ++) sum += W[Add_root[i]];
for(int i = ; i <= Cut_root[]; i ++) sum -= W[Cut_root[i]];
k -= sum;
if(k > ) return -;
return l;
}
int sum = ;
for(int i = ; i <= Add_root[]; i ++) sum += W[Lson[Add_root[i]]];
for(int i = ; i <= Cut_root[]; i ++) sum -= W[Lson[Cut_root[i]]];
int mid = (l + r) >> ;
if(k <= sum) {
for(int i = ; i <= Add_root[]; i ++) Add_root[i] = Lson[Add_root[i]];
for(int i = ; i <= Cut_root[]; i ++) Cut_root[i] = Lson[Cut_root[i]];
Asknum(l, mid, k);
} else {
for(int i = ; i <= Add_root[]; i ++) Add_root[i] = Rson[Add_root[i]];
for(int i = ; i <= Cut_root[]; i ++) Cut_root[i] = Rson[Cut_root[i]];
Asknum(mid + , r, k - sum);
}
}
} namespace Bit { inline int Lowbit(int x) {return (x & (-x));} void Add(int rt, int x, int val) {
for(int i = rt; i <= n; i += Lowbit(i)) {
Seg:: Insert(Root[i], , Length, x);
}
} int Getrank(int l, int r, int k) {
Add_root[] = Cut_root[] = ;
for(int i = r; i >= ; i -= Lowbit(i)) Add_root[++ Add_root[]] = Root[i];
for(int i = l - ; i >= ; i -= Lowbit(i)) Cut_root[++ Cut_root[]] = Root[i];
k = lower_bound(Num + , Num + Length + , k) - Num;
return Seg:: Getrank(, Length, k, );
} int Getnum(int l, int r, int k) {
Add_root[] = Cut_root[] = ;
for(int i = r; i >= ; i -= Lowbit(i)) {
Add_root[++ Add_root[]] = Root[i];
}
for(int i = l - ; i >= ; i -= Lowbit(i)) {
Cut_root[++ Cut_root[]] = Root[i];
}
return Seg:: Getnum(, Length, k);
} void Poi_G(int x, int k) {
Cut_root[] = ;
for(int i = x; i <= n; i += Lowbit(i)) Cut_root[++ Cut_root[]] = Root[i];
int a = lower_bound(Num + , Num + Length + , A[x]) - Num;
A[x] = k;
Seg:: Poi_G(, Length, a, -);
Cut_root[] = ;
for(int i = x; i <= n; i += Lowbit(i)) Cut_root[++ Cut_root[]] = Root[i];
a = lower_bound(Num + , Num + Length + , k) - Num;
Seg:: Poi_G(, Length, a, );
} int Asknum(int l, int r, int k, int opt) {
k = lower_bound(Num + , Num + Length + , k) - Num;
int kk = k;
Add_root[] = Cut_root[] = ;
for(int i = r; i >= ; i -= Lowbit(i)) Add_root[++ Add_root[]] = Root[i];
for(int i = l - ; i >= ; i -= Lowbit(i)) Cut_root[++ Cut_root[]] = Root[i];
k = Seg:: Getrank(, Length, k, );
Add_root[] = Cut_root[] = ;
for(int i = r; i >= ; i -= Lowbit(i)) Add_root[++ Add_root[]] = Root[i];
for(int i = l - ; i >= ; i -= Lowbit(i)) Cut_root[++ Cut_root[]] = Root[i];
int k2 = Seg:: Getrank(, Length, kk, );
Add_root[] = Cut_root[] = ;
for(int i = r; i >= ; i -= Lowbit(i)) Add_root[++ Add_root[]] = Root[i];
for(int i = l - ; i >= ; i -= Lowbit(i)) Cut_root[++ Cut_root[]] = Root[i];
if(opt == ) {
if(k == ) return -;
return Seg:: Asknum(, Length, k - );
}
else return Seg:: Asknum(, Length, k2 + );
}
} int main() {
n = read(), m = read();
for(int i = ; i <= n; i ++) Num[i] = read(), A[i] = Num[i];
totNum = n;
for(int i = ; i <= m; i ++) {
Ask[i].opt = read();
if(Ask[i].opt != ) {Ask[i].l = read(), Ask[i].r = read(), Ask[i].k = read();}
else Ask[i].l = read(), Ask[i].k = read(), Num[++ totNum] = Ask[i].k;
if(Ask[i].opt == || Ask[i].opt == ) {
Num[++ totNum] = Ask[i].k;
}
}
sort(Num + , Num + totNum + );
Length = unique(Num + , Num + totNum + ) - Num - ;
for(int i = ; i <= n; i ++) {
int a = lower_bound(Num + , Num + Length + , A[i]) - Num;
Bit:: Add(i, a, );
} #define opt Ask[i].opt
#define l Ask[i].l
#define r Ask[i].r
#define k Ask[i].k for(int i = ; i <= m; i ++) {
if(opt == ) {
cout << Bit:: Getrank(l, r, k) << "\n";
} else if(opt == ) {
int ans = Bit:: Getnum(l, r, k);
cout << Num[ans] << "\n";
} else if(opt == ) {
Bit:: Poi_G(l, k);
} else if(opt == ) {
int ans = Bit:: Asknum(l, r, k, );
if(ans == -) cout << "-2147483647" << "\n";
else cout << Num[ans] << "\n";
} else {
int ans = Bit:: Asknum(l, r, k, );
if(ans == -) cout << "" << "\n";
else cout << Num[ans] << "\n";
}
}
return ;
}

luogu 3380的更多相关文章

  1. bzoj 3196 && luogu 3380 JoyOI 1730 二逼平衡树 (线段树套Treap)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 题面; 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Se ...

  2. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

  3. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

  4. [luogu P2170] 选学霸(并查集+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...

  5. [luogu P2647] 最大收益(贪心+dp)

    题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...

  6. Luogu 考前模拟Round. 1

    A.情书 题目:http://www.luogu.org/problem/show?pid=2264 赛中:sb题,直接暴力匹配就行了,注意一下读入和最后一句话的分句 赛后:卧槽 怎么只有40 B.小 ...

  7. luogu P2580 于是他错误的点名开始了

    luogu  P2580 于是他错误的点名开始了 https://www.luogu.org/problem/show?pid=2580 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 他会一边 ...

  8. CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)

    CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...

  9. Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂)

    Luogu 1349 广义斐波那契数列(递推,矩阵,快速幂) Description 广义的斐波那契数列是指形如\[A_n=p*a_{n-1}+q*a_{n-2}\]的数列.今给定数列的两系数p和q, ...

随机推荐

  1. Kafka 的这些原理你知道吗

    如果只是为了开发 Kafka 应用程序,或者只是在生产环境使用 Kafka,那么了解 Kafka 的内部工作原理不是必须的.不过,了解 Kafka 的内部工作原理有助于理解 Kafka 的行为,也利用 ...

  2. 代码质量控制 & 编程注意项

    目录 代码质量控制 编程注意项 代码&功能优化 代码优化 功能&模块优化 其他 小技巧 调试 用于记录工作中出现的问题和编程时需要注意的重点,保证代码质量和编程效率     代码质量控 ...

  3. [PKUSC2018]主斗地(搜索+贪心)

    首先如果对子和三张牌出现在解中,那么全拆成单张显然没有问题,顺子同理.于是真正有用的牌型就只有单牌.三带一.三带二.四带二了. 暴搜jry手中的牌,然后先搜出双方的大牌型(即三张.四张牌的个数),再枚 ...

  4. idea下spring boot jpa写原生sql的时候,报Cannot resolve table错误

    错误如图 打开View→Tool Windows→Persistence选项 在弹出的Persistence窗口的项目上右键,选择Generate Persistence Mapping→By Dat ...

  5. GIL与线程进程小知识点

    一 .GIL全局解释器 GIL是一个互斥锁:保证数据的安全(以牺牲效率来换取数据的安全)阻止同一个进程内多个线程同时执行(不能并行但是能够实现并发)并发:看起来像同时进行的GIL全局解释器存在的原因是 ...

  6. 三种JS截取字符串方法

    JS提供三个截取字符串的方法,分别是:slice(),substring()和substr(),它们都可以接受一个或两个参数: var stmp = "rcinn.cn"; 使用一 ...

  7. Linux 非互联网环境安装依赖包

    1 介绍 有的生产环境是没有网络的,我们部署rpm包的时候会出现缺少很多rpm包的依赖问题,都去网上下载实在太麻烦,今天介绍一个办法可以解决这一问题. 2 解决方案 找一台可以联网的机器,在上边下载相 ...

  8. Web编程规范之三层架构设计规范

    本篇是我对Web开发规范中关于三层架构设计规范的一些浅见.虽然三层架构是比较普通,也比较简单的架构设计模式.但是随着业务的增长,涉及到的对象越来越多,处理的逻辑越来越复杂.这其中难免会出现设计不当,从 ...

  9. LTS秘钥协商算法分析

    1.根据RCF文档说法 在1-RTT中有两种密钥协商算法(1-RTT ECDHE和 1-RTT PSK  )和4中0-RTT密钥协商方式(0-RTT PSK, 0-RTT ECDH ,0-RTT EC ...

  10. klia linux tools 使用方法整理

    第一部分  信息收集工具 1.Zenmap 和nmap 作用是一样的,只是使用的操作方式不一样, Zenmap使用 的GUI,nmap 是基于命令行的.在两个使用的命令是一样的. 使用SYN扫描  就 ...