http://codeforces.com/contest/1284/problem/D
把区间对的第二维放入以第一维为下标的数轴中(如1 2 3 4,就把区间[3,4]放入位置1和位置2),如此同个位置的所有区间必须两两相交,即检验第一维相交?第二维相交。同理检验第二维相交?第一维相交。“放入”可用差分的方式。检验:新加入一个区间[x,y],必须满足y>=s_max,且x<=e_min,其中s和e是起点和终点。可用multiset维护加入、检测、删除。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 5 int n; 6 #define maxn 200011 7 struct AAA{int c,d,x,y;}a[maxn]; 8 struct EVE 9 { 10 int pos,x,y; bool ty; 11 bool operator < (const EVE &b) const 12 {return pos<b.pos || (pos==b.pos && ty<b.ty);} 13 }eve[maxn<<1]; int leve=0; 14 multiset<int> muls,mult; 15 16 #define IT multiset<int>::iterator 17 int main() 18 { 19 scanf("%d",&n); 20 for (int i=1;i<=n;i++) 21 { 22 scanf("%d%d%d%d",&a[i].c,&a[i].d,&a[i].x,&a[i].y); 23 eve[++leve]=(EVE){a[i].c,a[i].x,a[i].y,1}; 24 eve[++leve]=(EVE){a[i].d+1,a[i].x,a[i].y,0}; 25 } 26 sort(eve+1,eve+1+leve); 27 28 muls.clear(); mult.clear(); 29 for (int i=1;i<=leve;i++) 30 { 31 if (!eve[i].ty) muls.erase(muls.lower_bound(eve[i].x)),mult.erase(mult.lower_bound(eve[i].y)); 32 else 33 { 34 if (!muls.empty()) 35 { 36 IT it=muls.end(); it--; 37 if (eve[i].y<(*it)) {puts("NO"); return 0;} 38 it=mult.begin(); 39 if (eve[i].x>(*it)) {puts("NO"); return 0;} 40 } 41 muls.insert(eve[i].x),mult.insert(eve[i].y); 42 } 43 } 44 45 leve=0; 46 for (int i=1;i<=n;i++) 47 { 48 eve[++leve]=(EVE){a[i].x,a[i].c,a[i].d,1}; 49 eve[++leve]=(EVE){a[i].y+1,a[i].c,a[i].d,0}; 50 } 51 sort(eve+1,eve+1+leve); 52 53 muls.clear(); mult.clear(); 54 for (int i=1;i<=leve;i++) 55 { 56 if (!eve[i].ty) muls.erase(muls.lower_bound(eve[i].x)),mult.erase(mult.lower_bound(eve[i].y)); 57 else 58 { 59 if (!muls.empty()) 60 { 61 IT it=muls.end(); it--; 62 if (eve[i].y<(*it)) {puts("NO"); return 0;} 63 it=mult.begin(); 64 if (eve[i].x>(*it)) {puts("NO"); return 0;} 65 } 66 muls.insert(eve[i].x),mult.insert(eve[i].y); 67 } 68 } 69 70 puts("YES"); 71 return 0; 72 }
http://codeforces.com/contest/1284/problem/E
枚举中间点,其他点关于它极角排序后,除非四边形四个端点在过它的某条直线的同一侧,否则四边形一定可以包住它。因此枚举一个点,根据极角排序后的单调性找到最远的正好在“某条直线同侧”的点的下标,进行计数。注意,如果某个中间点对答案完全没贡献,即所有点关于它极角排序后都在同侧,可能导致死循环,需要特判。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 5 int n; 6 #define maxn 5011 7 LL cha(int x,int y,int xx,int yy) 8 { 9 return 1ll*x*yy-1ll*xx*y; 10 } 11 bool Area(int x,int y) 12 { 13 return !(x>0 || (x==0 && y>0)); 14 } 15 LL C(int n,int m) 16 { 17 LL ans=1; 18 for (int i=0;i<m;i++) ans*=n-i; 19 for (int i=1;i<=m;i++) ans/=i; 20 return ans; 21 } 22 23 struct POINT 24 { 25 int x,y; 26 bool operator < (const POINT &b) const 27 { 28 bool area1=Area(x,y),area2=Area(b.x,b.y); 29 if (area1<area2) return 1; 30 if (area1>area2) return 0; 31 return cha(b.x,b.y,x,y)>0; 32 } 33 }p[maxn],np[maxn]; int lnp; 34 35 int main() 36 { 37 scanf("%d",&n); 38 for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y); 39 40 LL ans=0; 41 for (int cen=1;cen<=n;cen++) 42 { 43 lnp=0; 44 for (int i=1;i<=n;i++) if (i!=cen) np[++lnp]=(POINT){p[i].x-p[cen].x,p[i].y-p[cen].y}; 45 sort(np+1,np+1+lnp); 46 47 // for (int i=1;i<=lnp;i++) cout<<np[i].x<<‘ ‘<<np[i].y<<endl; 48 // cout<<endl; 49 50 if (cha(np[lnp].x,np[lnp].y,np[1].x,np[1].y)>=0) continue; 51 bool skip=0; 52 for (int i=1;i<lnp;i++) if (cha(np[i].x,np[i].y,np[i+1].x,np[i+1].y)>=0) skip=1; 53 if (skip) continue; 54 55 ans+=C(lnp,4); 56 57 int j=1; 58 for (int i=1;i<=lnp;i++) 59 { 60 while (cha(np[j].x,np[j].y,np[i].x,np[i].y)>=0) j=(j==lnp?1:j+1); 61 // cout<<i<<‘ ‘<<j<<endl; 62 ans-=(j>i?C(j-i-1,3):C(lnp-i+j-1,3)); 63 } 64 // cout<<ans<<endl; 65 // cout<<endl; 66 } 67 printf("%lld\n",ans); 68 return 0; 69 }
。
原文地址:https://www.cnblogs.com/Blue233333/p/12228026.html
时间: 2024-11-02 10:19:21