Codeforces 612 D. The Union of k-Segments (非递归线段树+离散化)
来源:互联网 发布:linux 退出 编辑:程序博客网 时间:2024/05/17 07:10
题意:给定一堆线段,求最后重叠了k次或以上的线段和点。
先操作,最后一次下推标记,所以尽管是区间修改,非递归写起来还是很简单。
维护两个线段树,一个维护线段的覆盖,一个维护点的覆盖。
对于线段[L,R],点修改的区间是[L,R],
区间修改中,用线段的左端点代表这条线段,所以区间修改的区间是[L,R-1]
在所有操作都结束之后下推标记,然后从左到右扫描线段输出答案即可。
输出答案的时候,只有在没有线段覆盖了k次或以上的时候,才需要考虑是否有点被覆盖了k次或以上。
因为如果线段包含点的话,点就不需要独立输出了。
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#define maxn 1000007using namespace std;//离散化部分 int Rank[maxn<<1],Rn;void SetRank(){//排序+去除重复元素sort(Rank+1,Rank+1+Rn);int I=1;for(int i=2;i<=Rn;++i) if(Rank[i]!=Rank[i-1]) Rank[++I]=Rank[i];Rn=I;}int GetRank(int x){//得到某个元素离散化后的下标int L=1,R=Rn,M;while(L^R){M=(L+R)>>1;if(Rank[M]<x) L=M+1;else R=M;} return L;}//非递归线段树 int N; int Add[maxn<<3];//区间覆盖次数 int P[maxn<<3];//点覆盖次数 void Build(int n){//建树 N=1;while(N < n+2) N <<= 1;memset(Add,0,sizeof(Add));memset(P,0,sizeof(P));}void Update(int L,int R){//区间更新//线段更新 for(int s=N+L-1,t=N+R;s^t^1;s>>=1,t>>=1){if(~s&1) ++Add[s^1];if( t&1) ++Add[t^1]; }//点更新for(int s=N+L-1,t=N+R+1;s^t^1;s>>=1,t>>=1){if(~s&1) ++P[s^1];if( t&1) ++P[t^1]; }}void PushDown(){//下推所有标记for(int i=1;i<N;++i){Add[i<<1]+=Add[i];Add[i<<1|1]+=Add[i];P[i<<1]+=P[i];P[i<<1|1]+=P[i];}}int n,k,l[maxn],r[maxn];int main(void){while(~scanf("%d%d",&n,&k)){//输入 for(int i=Rn=0;i<n;++i){scanf("%d%d",&l[i],&r[i]);Rank[++Rn]=l[i];Rank[++Rn]=r[i];}//离散化 SetRank();//建树 Build(Rn);//更新树 for(int i=0;i<n;++i)Update(GetRank(l[i]),GetRank(r[i]));//下推标记 PushDown();//计算答案 int On=0,I=0;for(int i=1;i<=Rn;++i){//扫描覆盖情况if(Add[N+i]>=k){if(!On){//碰到线段的左端点,记录 l[++I]=Rank[i];On=1;}}else{if(On){//碰到线段的右端点,记录 r[I]=Rank[i];On=0;}else{//只有在不被线段覆盖时,才会考虑点是否被覆盖了k次或以上 if(P[N+i]>=k){//遇到被覆盖k次或以上的点,记录 l[++I]=Rank[i];r[I]=Rank[i];}}}}//输出结果 printf("%d\n",I);for(int i=1;i<=I;++i){printf("%d %d\n",l[i],r[i]);}}return 0;}
0 0
- Codeforces 612 D. The Union of k-Segments (非递归线段树+离散化)
- Codeforces 612D Educational Codeforces Round 4 D. The Union of k-Segments 离散化+map
- Codeforces 612D The Union of k-Segments 【思维】
- Codeforces 612D The Union of k-Segments
- CodeForces 612 D. The Union of k-Segments(水~)
- codeforces 612D The Union of k-Segments (sorting)
- CodeForces 612D The Union of k-Segments
- CodeForces 612D - The Union of k-Segments(模拟)
- Codeforces 612D The Union of k-Segments
- codeforces D. The Union of k-Segments 排序
- Educational Codeforces Round 4 D. The Union of k-Segments
- Educational Codeforces Round 4-D. The Union of k-Segments
- CF#The Union of k-Segments -离散化+树状数组
- Educational Codeforces Round 4 612D The Union of k-Segments(stl)
- ★codeforces 612D The Union of k-Segments (思维or类扫描线)
- codeforces 612D The Union of k-Segments (前缀和处理区间)
- CodeForces 612D The Union of k-Segments(排序+区间计数、扫描线)
- The Union of k-Segments CodeForces
- solr源码导入eclipse
- 数据结构与算法分析再读之引论和算法分析
- Scala使用withFilter减少中间数据产生
- 那些我们解过的bug之换状态栏没有sim卡的图标
- 关系型数据库管理系统
- Codeforces 612 D. The Union of k-Segments (非递归线段树+离散化)
- 正则表达式:Pattern类与Matcher类详解
- 自动化系统往后的模样
- js创建一个新的节点(不断补充)
- HDU1455Sticks(dfs剪枝)
- 【漫谈机器学习】1.误差做小VS概率概率最大(3)
- 无论怎样都不能生成R.java
- Github for Windows 1.0 版本的简单使用介绍
- android开源框架