题目
题意:
平面内
n
n
n个点,其中任意两点所在的直线上都不包含原点。
求一种集合的个数:
(
P
1
,
P
2
)
(
P
3
,
P
4
)
.
.
.
(
P
2
k
−
1
,
P
2
k
)
(P_1,P_2)(P_3,P_4)...(P_{2k-1},P_{2k})
(P1,P2)(P3,P4)...(P2k−1,P2k)使得:
1.不存在
i
!
=
j
,
P
i
=
P
j
i != j , P_i=P_j
i!=j,Pi=Pj.
2.不存在一对
i
!
=
j
,
(
P
2
i
−
1
,
P
2
i
)
(
P
2
j
−
1
,
P
2
j
)
i!=j,(P_{2i-1},P_{2i})(P_{2j-1},P_{2j})
i!=j,(P2i−1,P2i)(P2j−1,P2j)满足,圆
O
P
2
i
−
1
P
2
j
−
1
OP_{2i-1}P_{2j-1}
OP2i−1P2j−1和圆
O
P
2
i
P
2
j
OP_{2i}P_{2j}
OP2iP2j只有一个交点,圆
O
P
2
i
−
1
P
2
j
OP_{2i-1}P_{2j}
OP2i−1P2j和圆
O
P
2
i
P
2
j
−
1
OP_{2i}P_{2j-1}
OP2iP2j−1只有一个交点。
n < = 1000 n<=1000 n<=1000
圆反演之后可以推出对于
(
P
2
i
−
1
,
P
2
i
)
(
P
2
j
−
1
,
P
2
j
)
(P_{2i-1},P_{2i})(P_{2j-1},P_{2j})
(P2i−1,P2i)(P2j−1,P2j)需要满足
(
P
2
i
−
1
,
P
2
i
)
(P_{2i-1},P_{2i})
(P2i−1,P2i)和
(
P
2
j
−
1
,
P
2
j
)
(P_{2j-1},P_{2j})
(P2j−1,P2j)构成了平行四边形并且
P
2
i
−
1
P_{2i-1}
P2i−1和
P
2
i
P_{2i}
P2i是不相邻的顶点。
所以就是互相平分,求线段的中点然后统计一下就可以了。
A C C o d e \rm AC \ Code AC Code
#include<bits/stdc++.h>
#define maxn 600005
#define LL long long
using namespace std;
int n,m,w,a[maxn],b[maxn],c[maxn],idc[maxn],pdc[maxn],pda[maxn],ida[maxn],tg[maxn],mx[maxn];
bool cmp1(const int &u,const int &v){ return c[u] < c[v]; }
bool cmp2(const int &u,const int &v){ return b[u] < b[v]; }
int main(){
scanf("%d%d",&n,&w);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
if(b[i] - a[i] >= a[i]){
c[++c[0]] = a[i] , pdc[c[0]] = i;
c[++c[0]] = b[i] - a[i] , pdc[c[0]] = i;
}
else{
pda[++m] = i;
a[m] = a[i] , b[m] = b[i];
}
}
for(int i=1;i<=c[0];i++) idc[i] = i;
for(int i=1;i<=m;i++) ida[i] = i;
sort(idc+1,idc+1+c[0],cmp1);
sort(ida+1,ida+1+m,cmp2);
LL ans = 0x3f3f3f3f3f3f3f3fll , lc = 0 , la = 0 , lm = 0 , lq = 0 , sum = 0 , mxa = 0 , j = m;
for(int i=1;i<=m;i++){
sum += b[i];
if(i == 1) mx[i] = ida[1];
else mx[i] = b[ida[i]]-a[ida[i]] > b[mx[i-1]] - a[mx[i-1]] ? ida[i] : mx[i-1];
}
for(int i=0;i<=c[0];i++){
for(;j>=0 && j*2+i > w;j--){
sum -= b[ida[j]];
if(mxa == 0 || a[ida[j]] < a[mxa]) mxa = ida[j];
}
if(j < 0) break;
if(j * 2 + i == w){
if(sum < ans)
ans = sum , lc = i , la = j , lm = 0 , lq = 0;
}
else if(j*2+i+1 == w){
if(mxa && sum + a[mxa] < ans){
ans = sum + a[mxa] , lc = i , la = j , lm = mxa , lq = 0;
}
if(j < m && mx[j+1] && sum + b[ida[j+1]] - b[mx[j+1]] + a[mx[j+1]] < ans)
ans = sum + b[ida[j+1]] - b[mx[j+1]] + a[mx[j+1]] , lc = i , la = j+1 , lm = 0 , lq = mx[j+1];
}
sum += c[idc[i+1]];
}
printf("%lld\n",ans);
for(int i=1;i<=lc;i++) tg[pdc[idc[i]]]++;
for(int i=1;i<=la;i++) tg[pda[ida[i]]] += 2;
if(lm) tg[pda[lm]]++;
if(lq) tg[pda[lq]]--;
for(int i=1;i<=n;i++) printf("%d",tg[i]);
}