题意:

有两种操作:1.在[l,r]上插入一条值为val的线段 2.问p位置上值第k小的线段的值(是否存在)

特别的,询问的时候l和p合起来是一个递增序列

1<=l,r<=1e9;1<=val<=1e6; 1<=k<=1e9

思路:

因为l和p总体是递增的,第i个询问的p一定大于i之前所有操作的l,而前面能影响到i的答案的只有r>=p的线段。由此可以想到将l,r,p合起来离散化,从左往右扫描,遇到l,就在权值线段树上插入对应的val,遇到r就删除对应的val,而遇到询问时,当前的线段树必然对应了P点的所有线段,求一下全局第k小就能得到答案。

全局第k小除了利用权值线段树外,还能通过二分树状数组求得,复杂度比线段树多logn,但是实际测试好像还是树状数组快。

权值线段树

#include <bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn=2e5+5;//离散化值可能有两倍
struct node {
int opt,p,val,id;
operator<(node b) {
if(p!=b.p)
return p<b.p;
else if(opt==2)
return true;
else if(b.opt==2)
return false;
else
return id<b.id;
}
} P[maxn];
int cnt=0,n;
int T[maxn<<2];
inline void push_now(int k){
T[k]=T[k<<1]+T[k<<1|1];
}
void add(int rt,int l,int r,int p,int val){//[l,r]
if(l==r){
T[rt]+=val;
return;
}
int mid=(l+r)>>1;
if(p<=mid) add(lson,l,mid,p,val);
if(p>mid) add(rson,mid+1,r,p,val);
push_now(rt);
}
int query(int rt,int l,int r,int k){
if(T[rt]<k) return -1;
if(l==r) return l;
int mid=(l+r)>>1;
if(T[lson]>=k)
return query(lson,l,mid,k);
else
return query(rson,mid+1,r,k-T[lson]);
}
int lisan[maxn],tot=0;
int ans[maxn],acnt=0;
int main() {
int t,E;
cin>>t;
for(int kase=1; kase<=t; kase++) {
scanf("%d",&E);
tot=0;acnt=0;cnt=0;
for(int i=1; i<=E; i++)
T[i]=0;
int x,val,y,opt;
for(int i=1; i<=E; i++) {
scanf("%d%d%d",&opt,&x,&val);
if(opt==1) {
lisan[++tot]=val;
scanf("%d",&y);
P[++cnt]= {1,x,val,i};
P[++cnt]= {-1,y,val,i};
} else {
P[++cnt]= {2,x,val,i};
}
}
sort(lisan+1,lisan+1+tot);
n=unique(lisan+1,lisan+1+tot)-(lisan+1);
for(int i=1; i<=cnt; i++) {
if(P[i].opt!=2)
P[i].val=lower_bound(lisan+1,lisan+1+n,P[i].val)-lisan;
}
sort(P+1,P+1+cnt);
for(int i=1; i<=cnt; i++) {
if(P[i].opt!=2) {
add(1,1,n,P[i].val,P[i].opt);
}
else {
int temp=query(1,1,n,P[i].val);
if(temp==-1)
ans[++acnt]=-1;
else
ans[++acnt]=lisan[temp];
}
}
printf("Case %d:\n",kase);
for(int i=1; i<=acnt; i++) {
printf("%d\n",ans[i]);
}
}
}

树状数组+二分

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;//离散化值可能有两倍
struct node {
int opt,p,val,id;
operator<(node b) {
if(p!=b.p)
return p<b.p;
else if(opt==2)
return true;
else if(b.opt==2)
return false;
else
return id<b.id;
}
} P[maxn];
int cnt=0,n;
int T[maxn];
int lowbit(int x) {
return x&(-x);
}
int getsum(int p) {
int res=0;
while(p>0) {
res+=T[p];
p-=lowbit(p);
}
return res;
}
void add(int p,int val) {
while(p<=n) {
T[p]+=val;
p+=lowbit(p);
}
}
int query(int x) {
int l=0,r=n,mid;
while(r-l>1) {
mid=(r+l+1)/2;
if(getsum(mid)>=x)
r=mid;
else
l=mid;
}
return r;
}
int lisan[maxn],tot=0;
int ans[maxn],acnt=0;
int main() {
int t,E;
cin>>t;
for(int kase=1; kase<=t; kase++) {
scanf("%d",&E);
tot=0;
acnt=0;
cnt=0;
for(int i=1; i<=E; i++)
T[i]=0;
int x,val,y,opt;
for(int i=1; i<=E; i++) {
scanf("%d%d%d",&opt,&x,&val);
if(opt==1) {
lisan[++tot]=val;
scanf("%d",&y);
P[++cnt]= {1,x,val,i};
P[++cnt]= {-1,y,val,i};
} else {
P[++cnt]= {2,x,val,i};
}
}
sort(lisan+1,lisan+1+tot);
n=unique(lisan+1,lisan+1+tot)-(lisan+1);
for(int i=1; i<=cnt; i++) {
if(P[i].opt!=2)
P[i].val=lower_bound(lisan+1,lisan+1+n,P[i].val)-lisan;
}
sort(P+1,P+1+cnt);
for(int i=1; i<=cnt; i++) {
if(P[i].opt!=2) {
add(P[i].val,P[i].opt);
}
else {
int temp=query(P[i].val);
if(getsum(n)<P[i].val)
ans[++acnt]=-1;
else
ans[++acnt]=lisan[temp];
}
}
printf("Case %d:\n",kase);
for(int i=1; i<=acnt; i++) {
printf("%d\n",ans[i]);
}
}
}

最新文章

  1. CapsLock与ctrl的键位修改
  2. webform 上传
  3. JS通过身份证号码获取出生年月日
  4. .net破解一(反编译,反混淆-剥壳)
  5. 所有设备的CSS像素
  6. ASP.NET MVC中从前台页面视图(View)传递数据到后台控制器(Controller)方式
  7. MVC 详细说明
  8. vim命令/压缩和解压命令
  9. 奥运会订票系统c语言代写源码下载
  10. 一次Redis 的性能测试和问题
  11. linux shell 备注(一)
  12. .net基础学java系列(三)徘徊反思
  13. 953.Verifying an Alien Dictionary(Map)
  14. JS Object.defineProperties()方法
  15. .NET Core 实践二:事件通知和异步处理
  16. Linux基础命令---lp打印文件
  17. MySQL中的decimal
  18. docker_File 执行报错总结
  19. 搜索路径---PYTHONPATH 变量
  20. 利用js获取客户端ip的方法

热门文章

  1. Java连接SQL Server:jTDS驱动兼容性问题
  2. dp(不连续和)
  3. luoguP1965 转圈游戏(NOIP2013)(快速幂)
  4. flex布局解说和属性
  5. python学习三十四天函数高阶函数定义及用法
  6. httpclient请求接口,上传文件附加参数(.net core)
  7. What are draw calls(绘制命令) and what are batches(批)
  8. C语言实现读取文件所有内容到字符串
  9. Java疯狂讲义笔记——Lambda表达式
  10. squid代理与缓存(上)