计蒜客NOIP2017提高组模拟赛(三)day2-直线的交点

传送门

简单几何+逆序对

发现当两条直线甲乙与平板的交点在上面甲在较左的位置,那么下面甲在较右的位置就可以相交

然后把上面的位置排下序,下面离散化+树状数组即可

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #define INF 0x7f7f7f7f
11 #define pii pair<int,int>
12 #define pdd pair<double,double>
13 #define ll long long
14 #define MAXN 
15 using namespace std;
16 int n;
17 int K,A,B;
18 namespace solve1
19 {
20     int read(){
21         int x=0,f=1;char ch=getchar();
22         while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
23         while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
24         return x*f;
25     }
26     int dat[100005];
27     int n,N;
28     int sum(int k){
29         int ret=0;
30         while(k<=N){
31             ret+=dat[k];
32             k+=(k&-k);
33         }
34         return ret;
35     }
36     void add(int k){
37         while(k>=1){
38             dat[k]+=1;
39             k-=(k&-k);
40         }
41     }
42     pdd Node(int k1,int a1,int k2,int a2){
43         double x=1.0*(a2-a1)/(k1-k2);
44         double y=1.0*(k1*a2-k2*a1)/(k1-k2);
45         return make_pair(x,y);
46     }
47     int K,A,B;    
48     int k[100005],a[100005];
49     pdd b[100005];
50     pair<double,int> c[100005];
51     int d[100005];
52     void solve(){
53         K=::K,A=::A,B=::B;
54         n=::n;
55         for(int i=1;i<=n;i++){
56             k[i]=read();a[i]=read();
57         }
58         for(int i=1;i<=n;i++){
59             b[i]=make_pair(Node(k[i],a[i],K,A).first,Node(k[i],a[i],K,B).first);
60         }
61         sort(b+1,b+n+1);
62         for(int i=1;i<=n;i++){
63             c[i]=make_pair(b[i].second,i);
64         }
65         sort(c+1,c+n+1);
66         N=0;
67         for(int i=1;i<=n;i++){
68             if(1==i||c[i].first!=c[i-1].first){
69                 N++;
70             }
71             d[c[i].second]=N;
72         }
73         ll ans=0;
74         for(int i=1;i<=n;i++){
75             ans+=sum(d[i]);
76             add(d[i]);
77         }
78         printf("%lld\n",ans);
79     }
80 
81 }
82 int read(){
83     int x=0,f=1;char ch=getchar();
84     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
85     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
86     return x*f;
87 }
88 
89 int main()
90 {
91 //    freopen("data.in","r",stdin);
92     K=read();A=read();B=read();
93     n=read();
94     solve1::solve();
95     return 0;
96 }

 

posted @ 2017-10-27 22:37  white_hat_hacker  阅读(283)  评论(0编辑  收藏  举报