博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[luoguP3332] [ZJOI2013]K大数查询(树套树)
阅读量:5171 次
发布时间:2019-06-13

本文共 2207 字,大约阅读时间需要 7 分钟。

 

一开始想的是区间线段树套权值线段树,结果好像不能实现。

然后题解是权值线段树套区间线段树。

区间线段树上标记永久化就省去了pushdown的操作减少常数。

标记永久化的话。。yy不出来就看代码吧。

然后注意开long long

 

#include 
#include
#include
#define N 50010#define LL long longusing namespace std;int n, m, t, cnt;LL sum[N * 200];int opt[N], a[N], b[N], c[N], g[N], add[N * 200], ls[N * 200], rs[N * 200], root[N << 2];inline int read(){ int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f;}inline void insert2(int &now, int l, int r, int x, int y){ if(!now) now = ++cnt; if(x <= l && r <= y) { add[now]++; sum[now] += r - l + 1; return; } int mid = (l + r) >> 1; if(x <= mid) insert2(ls[now], l, mid, x, y); if(mid < y) insert2(rs[now], mid + 1, r, x, y); sum[now] = sum[ls[now]] + sum[rs[now]] + (LL)(r - l + 1) * add[now];}inline void insert1(int now, int l, int r, int d, int x, int y){ insert2(root[now], 1, n, x, y); if(l == r) return; int mid = (l + r) >> 1; if(d <= mid) insert1(now << 1, l, mid, d, x, y); else insert1(now << 1 | 1, mid + 1, r, d, x, y);}inline LL query2(int now, int l, int r, int x, int y){ if(x <= l && r <= y) return sum[now]; LL tmp = 0; int mid = (l + r) >> 1; if(x <= mid) tmp += query2(ls[now], l, mid, x, y); if(mid < y) tmp += query2(rs[now], mid + 1, r, x, y); return tmp + (LL)(min(r, y) - max(l, x) + 1) * add[now];}inline int query1(int now, int l, int r, LL d, int x, int y){ if(l == r) return l; int mid = (l + r) >> 1; LL tmp = query2(root[now << 1 | 1], 1, n, x, y); if(tmp < d) return query1(now << 1, l, mid, d - tmp, x, y); else return query1(now << 1 | 1, mid + 1, r, d, x, y);}int main(){ int i; n = read(); m = read(); for(i = 1; i <= m; i++) { opt[i] = read(); a[i] = read(), b[i] = read(), c[i] = read(); if(opt[i] == 1) g[++t] = c[i]; } sort(g + 1, g + t + 1); t = unique(g + 1, g + t + 1) - g - 1; for(i = 1; i <= m; i++) if(opt[i] == 1) { c[i] = lower_bound(g + 1, g + t + 1, c[i]) - g; insert1(1, 1, t, c[i], a[i], b[i]); } else printf("%d\n", g[query1(1, 1, t, c[i], a[i], b[i])]); return 0;}

  

转载于:https://www.cnblogs.com/zhenghaotian/p/8312768.html

你可能感兴趣的文章
有关快速幂取模
查看>>
NOI2018垫底记
查看>>
注意java的对象引用
查看>>
C++ 面向对象 类成员函数this指针
查看>>
NSPredicate的使用,超级强大
查看>>
自动分割mp3等音频视频文件的脚本
查看>>
判断字符串是否为空的注意事项
查看>>
布兰诗歌
查看>>
(转)Tomcat 8 安装和配置、优化
查看>>
(转)Linxu磁盘体系知识介绍及磁盘介绍
查看>>
跨域问题整理
查看>>
[Linux]文件浏览
查看>>
获取国内随机IP的函数
查看>>
Spring Mvc模式下Jquery Ajax 与后台交互操作
查看>>
(转)matlab练习程序(HOG方向梯度直方图)
查看>>
tableView
查看>>
Happy Great BG-卡精度
查看>>
TCP/IP 邮件的原理
查看>>
原型设计工具
查看>>
windows下的C++ socket服务器(4)
查看>>