当前位置: 首页 > news >正文

P2161 [SHOI2009] 会场预约

思路1: A操作中,要知道有多少个区间是重合的,可以用(树状数组+二分)来维护,用树状数组c[i]维护以i为端点的区间,  将[l,r] 进行二分查询从左端点到0~r右端点,然后判断当前区间是否在选定大区间内,如果query(mid)==query(r)说明重合个数相同,将其删去

B操作只需要用一个全局变量ans记录即可

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,x,y,c[N],a[N],ans=0,anss=0;
int lowbit(int x){return x&(-x);
}
void add(int x,int y){for(int i=x;i<=N;i+=lowbit(i)) c[i]+=y;
}
int query(int x){int res=0;for(int i=x;i;i-=lowbit(i)) res+=c[i];return res;
}
int main(){cin>>n;for(int i=1;i<=n;i++){char ch;cin>>ch;if(ch=='A') {cin>>x>>y;anss=0;while(1){int l=0,r=y;while(l<r){int mid=l+r>>1;if(query(mid)<query(y)) l=mid+1;else r=mid;}if(a[l]>=x){add(l,-1);anss++;ans--;}else break;}add(x,1);a[x]=y;ans++;cout<<anss<<endl;}else cout<<ans<<endl;}return 0;
}
/*
6
A 10 15
A 17 19
A 12 17
A 90 99
A 11 12
B
*/

思路2

用平衡树对区间进行维护。

可以注意到的是,对于当前存在的预约,他们一定是升序排列的(有重叠的都被删了)。

那么就可以用按照位置分裂(预约无论按l还是按r都必定是升序的)。

每次插入一个区间的时候,就直接找出互不重叠的前驱和后继,那么需要删除的就是中间的那一段了(因为区间升序),对于每一个A的答案就是中间那段的siz,合并的时候注意一下顺序

对于B询问,答案就是root的siz

#include<bits/stdc++.h>
#define ll long long
#define lc (t[rt].l)
#define rc (t[rt].r)
using namespace std;
const int N=2e5+10;
int lt;
struct node{ int l,r; 
};
struct fhq { int l,r,siz,rnd; node v; 
}t[N];
int ct,rt;
char ch[10];
void up(int rt){t[rt].siz=t[lc].siz+t[rc].siz+1;
}
void split(int rt,int &l,int &r,int k){if(!k) l=0,r=rt;else if(t[rt].siz==k) l=rt,r=0;else if(k<=t[lc].siz)r=rt,split(lc,l,lc,k),up(rt);else l=rt,split(rc,rc,r,k-t[lc].siz-1),up(rt);
}
void merge(int &rt,int l,int r) {if(!l||!r) rt=l+r;else if(t[l].rnd<t[r].rnd) rt=l,merge(rc,rc,r),up(rt);else rt=r,merge(lc,l,lc),up(rt);
}
int pre(int rt,node a) {if(!rt) return 0;if(t[rt].v.r<a.l) return pre(rc,a)+t[lc].siz+1;else return pre(lc,a);
}
int nxt(int rt,node a) {if(!rt) return 0;if(t[rt].v.l>a.r)return nxt(lc,a);else return nxt(rc,a)+t[lc].siz+1;
}
int new_node(node a){t[++ct].v=a,t[ct].siz=1;t[ct].rnd=rand()<<15|rand(),t[ct].l=t[ct].r=0;return ct;
}
int build(node a) {int l=pre(rt,a),r=nxt(rt,a),x,y,z,k;split(rt,x,y,r); split(x,z,k,l);int ans=t[k].siz,t=new_node(a);merge(t,z,t);merge(rt,t,y); return ans;
}
int main() {node a;srand((unsigned)time(0));scanf("%d",&lt);while(lt--) {scanf("%s",ch);if(ch[0]=='A') {scanf("%d%d",&a.l,&a.r);printf("%d\n",build(a));}else printf("%d\n",t[rt].siz);}return 0;
}

        

http://www.dtcms.com/a/316257.html

相关文章:

  • 中山铸造加工件自动蓝光三维测量方案-中科米堆CASAIM
  • 喷砂机常见故障及排除维修解决方法有哪些?
  • 猎板深度解析:EMI 干扰 —— 电子设备的隐形 “破坏者”
  • Dot1x认证原理详解
  • 利用 Radius Resource Types 扩展平台工程能力
  • 在 QtC++ 中调用 OpenCV 实现特征检测与匹配及图像配准应用
  • Linux DNS缓存与Nginx DNS缓存运维文档
  • 数据结构 | 树的秘密
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘pytorch-lightning’问题
  • 机器学习之线性回归与逻辑回归
  • 网络muduo库的实现(2)
  • 计算机算术5-整形除法
  • MySql数据库归档工具pt-archiver
  • Android audio之 AudioDeviceInventory
  • 第三方验收测试报告:软件项目验收中的核心要素
  • 前端权限设计
  • Pandas query() 方法详解
  • 涨薪技术|Kubernetes(k8s)之Pod生命周期(上)
  • Deveco Studio 3.1.0.501 Windows版下载安装教程 - 华为开发者工具安装步骤详解
  • BenchmarkDotNet 性能基准测试
  • 统计鱼儿分布情况 Java
  • 三种灰狼算法求解无人机三维路径规划【MATLAB实现】
  • 2025国赛数学建模C题详细思路模型代码获取,备战国赛算法解析——层次分析法
  • MATLAB实现菲涅尔法全息成像仿真
  • Groovy学习篇章一之—— GDK 探秘:Groovy如何给Java对象“开外挂”,让String也能“跑命令”!
  • 磁悬浮转子的“静音术”:深度解析无接触抑制旋转幽灵的奥秘
  • 基于MCP的智能客服系统:知识库与工单系统深度集成
  • 英语中日期与时间缩写
  • 针对软件定义车载网络的动态服务导向机制
  • CoRL-2025 | 北大“如影随形”具身导航智能体!TrackVLA:复杂自然环境中的具身视觉跟踪