就是有
n
n
n堆石头,每次可以将一堆中的一个石头放到另一堆中,对应代价为
1
1
1,当所有对的石头数量有一个大于1的公共因子
K
K
K的时候游戏结束,求游戏结束时的最小代价
题解
首先如果所有石堆都有一个公共因子的话,那么他们的和
s
u
m
sum
sum也是这个因子的倍数,枚举
s
u
m
sum
sum的质因子,然后对于一个质因子
p
i
p_i
pi,将所有
a
i
%
p
i
a_i\%p_i
ai%pi排序,从大到小满足所有数,即让这个数变成
p
i
p_i
pi产生的代价为
p
i
−
(
a
i
%
p
i
)
p_i-(a_i\%p_i)
pi−(ai%pi),至于为什么不会是
2
p
i
2p_i
2pi,那么这种情况下只会是至少3个数拼到一堆,对应的代价为所有较小的
n
u
m
−
1
num-1
num−1之和,那么还不如合并成多堆大小为
p
i
p_i
pi的数,代价更小
复杂度
O
(
n
log
n
log
1
0
9
)
O(n\log n\log 10^9)
O(nlognlog109)
就是给你
n
n
n个区间
[
l
i
,
r
i
]
[l_i,r_i]
[li,ri],每个区间有两个属性
A
A
A和
B
B
B,然后让你选择这些区间的一个自己
S
S
S,在所有
S
S
S中的区间覆盖区间
[
1
,
t
]
[1,t]
[1,t]的情况下使得下面这个式子最小
∑
i
∈
S
A
i
∑
i
∈
S
B
i
\frac{\sum_{i\in S}^{}{A_i}}{\sum_{i\in S}^{}{B_i}}
∑i∈SBi∑i∈SAi
题解
显然是一个
01
01
01规划问题,二分之后关键在于怎么
c
h
e
c
k
check
check,令
∑
i
∈
S
A
i
∑
i
∈
S
B
i
≤
m
i
d
\frac{\sum_{i\in S}^{}{A_i}}{\sum_{i\in S}^{}{B_i}}\leq mid
∑i∈SBi∑i∈SAi≤mid 得
∑
i
∈
S
A
i
−
m
i
d
×
B
i
≤
0
\sum_{i\in S}^{}{A_i-mid\times B_i}\leq 0
i∈S∑Ai−mid×Bi≤0 那么对于
A
i
−
m
i
d
×
B
i
≤
0
A_i-mid\times B_i \leq 0
Ai−mid×Bi≤0的区间直接选,然后对于大于0的区间考虑选择一些满足未覆盖的区间,考虑用线段树维护做一个
d
p
dp
dp,即用
d
p
[
i
]
dp[i]
dp[i]表示覆盖区间
[
1
,
i
]
[1,i]
[1,i]对应的最小代价,然后对于一个区间
[
l
i
,
r
i
]
[l_i,r_i]
[li,ri],更新
d
p
[
r
i
]
=
min
j
=
l
i
−
1
r
i
d
p
[
j
]
+
m
a
x
(
0
,
A
i
−
m
i
d
×
B
i
)
dp[r_i]=\min_{j=l_i-1}^{r_i}{dp[j]}+max(0,A_i-mid\times B_i)
dp[ri]=minj=li−1ridp[j]+max(0,Ai−mid×Bi),取
m
a
x
max
max的原因是对于负的区间代价为0
复杂度
O
(
n
log
n
log
m
)
O(n \log n \log m)
O(nlognlogm)
首先需要注意到如果黑点个数如果为
k
k
k能满足所有描述,那么
k
+
1
k+1
k+1也一定能满足所有描述,即问题满足单调性,考虑二分
对于一个二分的值
m
i
d
mid
mid,尝试将第二种描述转化一下,即转化为以
x
i
x_i
xi为根的子树最多有
m
i
d
−
y
i
mid-y_i
mid−yi个黑点,那么这样的话每个节点对应的子树黑点个数对应一个可行的数量区间,然后做一个简单的树形
d
p
dp
dp,即计算满足所有以节点
i
i
i为根的子树的所有条件的情况下当前节点的子树黑点数量可行区间,那么如果
m
i
d
mid
mid在节点1对应的区间里,则可行
就是给你
n
n
n个点,然后让你求一个圆,使得至少有
⌈
n
2
⌉
\lceil \frac{n}{2}\rceil
⌈2n⌉个点在圆上
题解
由于至少有一半的点在圆上,又因为三个不再同一条直线上的点可以确定一个圆,那么考虑随机出这三个点,然后
O
(
n
)
O(n)
O(n)去
c
h
e
c
k
check
check所有点是否在圆上,由于三个点都在构成答案的点集中的概率为
1
8
\frac{1}{8}
81,所以期望随机次数为
8
8
8即可得到答案
打虚拟赛的时候由于最后才想起来随机,忘记特判
n
≤
4
n\leq4
n≤4的情况导致一直随机而
T
L
E
TLE
TLE,然后交了一发比赛就结束了
Q
W
Q
QWQ
QWQ
复杂度
O
(
n
)
O(n)
O(n)
代码
#include<bits/stdc++.h>
using namespace std;constint maxn=1e5+10;#defineeps1e-4#definepiacos(-1.0)intsgn(double k){return k<-eps?-1:(k<eps?0:1);}structpoint{double x,y;point(double a=0,double b=0){x=a;y=b;}
point operator*(double k){returnpoint(x*k,y*k);}double operator*(point other){return x*other.x+y*other.y;}double operator^(point other){return x*other.y-y*other.x;}
point operator/(double k){returnpoint(x/k,y/k);}
point operator+(point other){returnpoint(x+other.x,y+other.y);}
point operator-(point other){returnpoint(x-other.x,y-other.y);}
friend doublelen(point p){returnsqrt(p.x*p.x+p.y*p.y);}
friend point rotate(point p1,point p2,double a){
point vec=p2-p1;double xx=vec.x*cos(a)+vec.y*sin(a);double yy=vec.y*cos(a)-vec.x*sin(a);returnpoint(p1.x+xx,p1.y+yy);}}p[maxn];structline{
point s,e;line(){}line(point a,point b){s=a;e=b;}
friend point intersect(line l1,line l2){double k=((l2.e-l2.s)^(l2.s-l1.s)/((l2.e-l2.s)^(l1.e-l1.s)));return l1.s+(l1.e-l1.s)*k;}};structcircle{
point o;double r;circle(){}circle(point a,point b,point c){
point p1=rotate((a+b)/2,b,3*pi/2),p2=rotate((b+c)/2,c,3*pi/2);
o=intersect(line((a+b)/2,p1),line((b+c)/2,p2));
r=len(o-a);}};int n;intmain(){srand(998244353);int t;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lf %lf",&p[i].x,&p[i].y);
circle res;if(n==1){printf("%.10lf %.10lf %.10lf\n",p[1].x,p[1].y,0);continue;}elseif(n<=4){printf("%.10lf %.10lf %.10lf\n",(p[1].x+p[2].x)/2,(p[1].y+p[2].y)/2,len(p[2]-p[1])/2);continue;}for(;;){int x=rand()%n+1,y=rand()%n+1,z=rand()%n+1;if(x==y||x==z||y==z||(sgn((p[y]-p[x])^(p[z]-p[x]))==0))continue;
circle o=circle(p[x],p[y],p[z]);int cnt=0;for(int i=1;i<=n;i++)if(sgn(o.r-len(p[i]-o.o))==0) cnt++;if(cnt>=(n+1)/2&&fabs(o.o.x)<=1e9&&fabs(o.o.y)<=1e9&&fabs(o.r)<1e9){res=o;break;}}printf("%.10lf %.10lf %.10lf\n",res.o.x,res.o.y,res.r);}}