题意:
任意找出两个区间,使得一个区间含于另一个区间。不存在输出-1 -1;
思路:
一、可以对区间按照左边界从小到大,右边界从大到小排序。遍历数组,如果存在前一个区间含于本区间,则输出;否则不存在。可以简单验证一下。
扫描二维码关注公众号,回复:
527090 查看本文章
代码
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define inf 1<<29 #define MAXN 300005 #define ll long long int n,m; struct node { int l,r,id; }p[MAXN]; bool cmp(node a,node b) { return a.l==b.l? a.r>b.r:a.l<b.l; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&p[i].l,&p[i].r); p[i].id=i; } sort(p,p+n,cmp); for(int i=0;i<n-1;i++) { if(p[i+1].l>=p[i].l && p[i+1].r<=p[i].r) { printf("%d %d\n",p[i+1].id+1,p[i].id+1); exit(0); } } printf("-1 -1\n"); return 0; }
思路二:利用splay,每次插入一个区间,插入时如果碰到一个区间含于或包含它,则跳出程序。否则按照左区间的大小进行插入。全部成功插入则输出-1 -1.
#include <cstdio> #include<cstring> #include <algorithm> #define maxn 300005 using namespace std; const int inf=~0u>>2; #define lc(x) ch[(x)][0] #define min(x,y) (x)>(y)?(y):(x) int fa[maxn],ch[maxn][2],root,ind=1; int a[maxn][2]; struct data { int l,r,id; }k[maxn]; inline void rotate(int p) { int q=fa[p],y=fa[q],x=ch[q][1]==p; ch[q][x]=ch[p][x^1];fa[ch[q][x]]=q; ch[p][x^1]=q;fa[q]=p; fa[p]=y; if(y) { if(ch[y][0]==q)ch[y][0]=p; else if(ch[y][1]==q)ch[y][1]=p; } } inline void splay(int x) { for(int y;y=fa[x];rotate(x)) if(fa[y]) rotate((x==lc(y))==(y==lc(fa[y]))?y:x); root=x; } inline void insert(int x,int vl,int vr,int id) { int y; while(true) { if(k[x].l<=vl && vr<=k[x].r) { printf("%d %d\n",id,k[x].id); exit(0); } if(vl<=k[x].l && k[x].r<=vr) { printf("%d %d\n",k[x].id,id); exit(0); } y=ch[x][k[x].l<vl]; if(y==0) { y=++ind; k[y].l=vl; k[y].r=vr; k[y].id=id; ch[y][0]=ch[y][1]=0; fa[y]=x; ch[x][k[x].l<vl]=y; break; } x=y; } splay(y); } int main() { int n,ans=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i][0],&a[i][1]); } root=1; k[1].l=a[1][0]; k[1].r=a[1][1]; k[1].id=1; ch[root][0]=ch[root][1]=0; fa[root]=0; for(int i=2;i<=n;i++) { insert(root,a[i][0],a[i][1],i); } printf("-1 -1\n"); return 0; }