LA 6348 数据结构

想法题:

   坑爹细节没想清楚就敲了 。。  整体的思路 在更新的时候出了问题。 10WA->AC 。。

   战绩成渣了。。。 弱渣的艰辛奋斗史。,。。

 

  题意是 :

 给出 n个矩形,问每一个外边的那个矩形 的编号。 (0 ->  n-1)

 

 性质: 对于矩形 a,b   ,若 a.x2 <= b.x1 ,b 矩形不会在 a矩形中 ,所以 所有的 x1 >b.x1的矩形 同样不会在a 矩形中。(单调形)。

性质2:若 a.x2 > b.x1  并且  a.y1< b.y1 < a.y2 或者 a.y1 < b.y2 < a.y2 时 ,b 矩形必定在 a 矩形中。

根据这两个性质 此问题就简化了不少。 

根据这个性质,就可以对 x1 进行排序, 按 x1 的顺序依次把 y1 -y2 这个区间更新。

  用线段树维护 y 值。 这样就把一个二维的问题,简化为一维的简单。 

难点 : update  更新操作,删除矩形时,要把 此矩形的 外围矩形 的值更新上 。

也就是   把这个要删除的矩形的y区间更新为外围矩形的 id。而不是简单的更新为-1 或者 把整个外围矩形的 y 区间更新为id。

想法想不全 是硬伤。。。 考虑不全。  接下来的长沙赛区 我都不想打 代码了。。 就算数据结构题,也要让队友给我考虑一下的 模型 的操作 是否能达到预期的值。

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <cstring>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <assert.h>
#include <queue>
#define REP(i,n) for(int i=0;i<n;i++)
#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define ALLL(x) x.begin(),x.end()
#define SORT(x) sort(ALLL(x))
#define CLEAR(x) memset(x,0,sizeof(x))
#define FILLL(x,c) memset(x,c,sizeof(x))
using namespace std;
const double eps = 1e-9;
#define LL long long 
#define pb push_back
const int maxn  = 210000;
map<int,int >mpx,mpy;
map<int,int>::iterator it;
struct S{
	int id;
    int x1,y1,x2,y2;
    bool operator <(const S &b)const{
    	return x1<b.x1;
    }
}s[maxn],s2[maxn];
int n;
struct Node{
	int num;
	int flag;
}node[maxn*4];
void build(int i,int left ,int right){
	node[i].flag = -2;
	node[i].num =-1;
	 if(left == right){
	 	 node[i].num =-1;
	 	 node[i].flag = -2;
	 	 return ;
	 }
	 int mid = (left +right)>>1;
	 build(i<<1,left,mid);
	 build(i<<1|1,mid+1,right);
}
void pushdown(int i){
	 if(node[i].flag >-2){
	 	  node[i<<1].flag = node[i<<1].num = node[i<<1|1].flag = node[i<<1|1].num = node[i].flag;  
	 }
	 node[i].flag = -2;
}
void update(int i,int left ,int right,int L ,int R,int val){
//	cout << L <<" **  "<<R << "  "<<left << " "<<right<<endl;
	   if(L<= left && right<=R){
	   	    node[i].num = val;
	   	    node[i].flag = val;
	   	    return ;
	   }
	   pushdown(i);
	   int mid = (left+right)>>1;
	   if(L<=mid){
	   	   update(i<<1,left,mid,L,R,val);
	   }
	   if(R>mid){
	   	    update(i<<1|1,mid+1,right,L,R,val);
	   }
}
int query(int i,int left ,int right,int pos){
	if(left ==right){
		return node[i].num;
	}
	int mid = (left +right)>>1;
	
	pushdown(i);
	if(pos<=mid){
		return query(i<<1,left,mid,pos);
	}else{
		return query(i<<1|1,mid+1,right,pos);
	}
}
struct Node2{
	int x2;
	int id2;
	bool operator < (const Node2  &b)const {
		 return x2>b.x2;
	}
};
priority_queue<Node2>pq;
int ans[maxn];
int f[maxn];
int f_idx[maxn];
void solve(){
	 build(1,1,2*n);
	 while(!pq.empty()){
	 	pq.pop();
	 }
	 for(int i=1;i<=n;i++){
	 	   int x1 = s[i].x1;
	 	   int x2 = s[i].x2;
	 	   while(!pq.empty()){
	 	   	    Node2 t = pq.top();
	 	   	    if(t.x2<=x1){
	 	   	    	 pq.pop();
	 	   	    	 int id2 = t.id2;
	 	   	    	 int id3 = f[id2];
	 	   	    	 update(1,1,2*n,s[id2].y1,s[id2].y2,id3);
	 	   	    }else{
	 	   	    	break;
	 	   	    }
	 	   }
	 	   Node2 p = (Node2){x2,i};
	 	   pq.push(p);
	 	   int ttt = query(1,1,2*n,s[i].y1);
	 	   ans[s[i].id]= ttt;
	 	   f[i] =ttt;
	 	   update(1,1,2*n,s[i].y1,s[i].y2,s[i].id-1);
	 	  // cout << s[i].y1 << " "<<s[i].y2 << " " <<s[i].id-1<<endl;
	 }
	 for(int i=1;i<=n;i++){
	 	 printf("%d\n",ans[i]);
	 }
}

int main(){
    while(~scanf("%d",&n)){
    	mpx.clear();
    	mpy.clear();
    	 for(int i=1;i<=n;i++){
    	 	s[i].id = i;
    	 	scanf("%d%d%d%d",&s[i].x1,&s[i].y1,&s[i].x2,&s[i].y2);

    	 	mpx[s[i].x1] =1;
    	 	mpx[s[i].x2] =1;
    	 	mpy[s[i].y1] =1;
    	 	mpy[s[i].y2] =1;
    	 }
    	 int tot =0;
    	 for(it = mpx.begin();it != mpx.end() ;it++){
    	 	  tot ++ ;
    	 	  it->second = tot;
    	 }
    	 tot = 0 ;
    	 for(it =mpy.begin();it!= mpy.end();it++){
    	 	  tot ++ ;
    	 	  it->second = tot;
    	 }
    	 for(int i=1;i<=n;i++){
    	 	  s[i].x1 = mpx[s[i].x1];
    	 	  s[i].x2 = mpx[s[i].x2];
    	 	  s[i].y1 = mpy[s[i].y1];
    	 	  s[i].y2 = mpy[s[i].y2];
    	 	      	 	s2[i].x1 = s[i].x1;
    	 	s2[i].x2 = s[i].x2;
    	 	s2[i].y1 = s[i].y1;
    	 	s2[i].y2 = s[i].y2;
    	 }
    	 sort(s+1,s+n+1);
    	 solve();
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值