Codeforces Hello 2020 选讲

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 }
View Code

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 }
View Code

posted @ 2020-01-28 10:55  Blue233333  阅读(204)  评论(0编辑  收藏  举报