想法题:
坑爹细节没想清楚就敲了 。。 整体的思路 在更新的时候出了问题。 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;
}