======= 2020/05/23-2020/05/30周报 ======= ====== 团队训练 ====== 2020.5.27 [[2018-2019 ACM-ICPC, Asia Jiaozuo Regional Contest]] ====== 李元恺 ====== 又摸了一周 ====== 姜维翰 ====== ===== 专题 ===== 没有专题 ===== 比赛 ===== 没有比赛 ===== 题目 ===== ====== 袁熙 ====== ===== 专题 ===== 没有专题 ===== 比赛 ===== 没有比赛 ===== 题目 ===== (暂放上周团队训练补题)\\ B.Tournament wqs二分,单调队列\\ 题意:x轴上有n个点$a_1,..,a_n$,选择x轴上k个位置$x_1,..,x_k$,使$\sum_{i=1}^{n}\sum_{j=1}{k}|a_i-x_j|$最小\\ 数据范围n<=3*10^5,a_i<=10^9\\ 思路:直接dp是$O(n^3)$的。对在选择数量上有约束的dp,可以考虑wqs二分来降维;再考虑dp的过程中,具有决策单调性。 对由j转移到的i,$ {\forall} i'>i $,对应的转移前的$j'>j$(一定是向更后面选位置$x_i$)。双向队列维护前述的性质,dp就可以$O(nlog^2n)$做 \\ 代码 #include #define ll long long #define tmp(x) std::cout<<"& "<<(x)<<" &\n" #define rep(i,a,b) for(int i=(a);i<=(b);++i) #define per(i,a,b) for(int i=(a);i>=(b);--i) using namespace std; const int maxn=3e5+100; const int mo=998244353; int n,k,st,ed; int a[maxn],q[maxn],pos[maxn],cnt[maxn],tmp; ll w[maxn],s[maxn]; inline ll getv(int i,int j){return s[i]+s[j]-s[i+j>>1]-s[i+j+1>>1];} inline bool cmp(int a,int b,int c){ ll a1=w[a]+getv(a,c),b1=w[b]+getv(b,c); if(a1==b1)return cnt[a]>1; if(cmp(i,q[ed],m))r=m; else l=m+1; } if(l<=n)q[++ed]=i,pos[ed]=l; } return cnt[n]; } int main(){ // freopen("in.txt","r",stdin); scanf("%d%d",&n,&k); rep(i,1,n) scanf("%d",&a[i]),s[i]=s[i-1]+a[i]; ll l=0,r=s[n]+1; while(l+1>1; tmp=work(mid); if(tmp>=k)l=mid+1; else r=mid; } if(work(l)<=k)printf("%lld",w[n]-k*l); else if(work(l+1)<=k)printf("%lld",w[n]-k*(l+1)); return 0; } D.Country Meow 三分\\ 题意:三维空间有100个点,求他们的最小球覆盖(最小化到这些点的距离最大值)\\ 思路:最小圆覆盖模板/三分 \\ 三分:对x,y,z轴之一,所求值关于因变量是一个单峰函数。三分找到关于各个轴的最优位置即可。\\ 代码 #include using namespace std; const int maxn=1000000; struct point{ double d[3]; }p[110],pl,pr,m1,m2; int n; inline double dis(point a,point b){ return sqrt((a.d[0]-b.d[0])*(a.d[0]-b.d[0])+(a.d[1]-b.d[1])*(a.d[1]-b.d[1])+(a.d[2]-b.d[2])*(a.d[2]-b.d[2])); } double work(int pos,double v){ double l=-1e6,r=1e6,ans=1e9; if(pos)m1.d[pos-1]= m2.d[pos-1]=v; while(abs(l-r)>1e-3){ double r1=0,r2=0; if(pos!=2)r1=work(pos+1,(2*l+r)/3),r2=work(pos+1,(l+r*2)/3); else{ m1.d[pos]=(2*l+r)/3,m2.d[pos]=(l+2*r)/3; for(int i=1;i<=n;++i)r1=max(r1,dis(p[i],m1)),r2=max(r2,dis(p[i],m2)); } (r1>r2)?l=(2*l+r)/3:r=(l+r*2)/3; ans=min(r1,r2); } return ans; } int main(){ // freopen("in.txt","r",stdin); scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%lf%lf%lf",&p[i].d[0],&p[i].d[1],&p[i].d[2]); } printf("%.9lf\n",work(0,0)); return 0; } ====== 本周推荐 ====== ===== 姜维翰 ===== ===== 袁熙 ===== 推荐三分