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