BZOJ 4014 FJOI2014 病毒防护带

4014: [FJOI2014]病毒防护带

Time Limit: 20 Sec  Memory Limit: 512 MBSec  Special Judge
Submit: 262  Solved: 17
[Submit][Status][Discuss]

Description

众所周知,在国王胖哥的带领下,K国国泰民安,空前繁荣,但今天K国却遇到了空前的危机。
在K国境内同时发现了n个未知的病毒,每个病毒会从它被发现的位置开始感染K国的土地,K国可以看做是一个无限大的二维平面,而病毒的感染形状可以看做是一个不断扩大的圆形区域,即在t时间这个病毒会感染半径为t的圆形土地,这个圆形的圆心为发现这个病毒的位置。
但是万幸的是,K国有独特的病毒防护带可以杀死这些病毒,所以K国国王胖哥在刚发现病毒之时就开始着手进行杀毒工作,所谓的病毒防护带可以看成是一条直线,可以选定建立在K国的任意位置,即可以放置在K国所表示的平面上的任意位置,一旦病毒在扩散的过程中接触到这个防护带,病毒就会死亡,它感染的土地面积就固定为这个病毒死亡时所占的土地面积。注意由于防护带的建立十分昂贵,K国最多只能建立一条病毒防护带。
现在胖哥想知道要如何设立这个病毒防护带,才能使每个病毒感染的平均面积最小,即被感染的总土地面积除以病毒数n,每个病毒可以独立看待,即任意一个病毒的死亡不会影响到其他的病毒。注意如果同一个区域被多个病毒感染,那么在计算被感染的土地面积时需要计算多次,即若有一个病毒在位置(0,0)被发现,一个病毒在位置(1,1)被发现,它们都在t=1时接触到防护带死亡,那么此时K国被感染的面积为pi*2,病毒感染的平均面积为pi。
由于K国有举世无双的安全监测系统和卫生防护系统,可以认为在病毒防护带建立完毕之后病毒才开始进行扩散。若病毒出现在病毒防护带上,他感染的土地面积可以看做0。
请编程输出在最优决策下,这些病毒感染的平均面积。
 

 

Input

第1行中给出正整数Q,表示该组数据中有多少组测试样例。
每组样例首先输入一个整数n (0 < n ≤ 1000000),表示该组样例中病毒的个数,之后一行输入两个正整数x,y,表示第一个病毒的坐标,之后一行输入三个正整数a,b,c,如果第i个病毒的坐标为(x, y),那么第i+1个病毒的坐标为(x’, y’),其中x’=(a*x*x + b*x + c)%107,y’=(a*y*y + b*y + c)%107,其中%是取模运算符号
 

 

Output

首先输出样例编号,之后输出在最优决策下,这些病毒会感染的K国的土地面积,答案保留8位小数,详见输出示例,请严格按照输出实例中的格式输出
 

 

Sample Input

2
2
0 0
0 0 1
3
1 2
3 4 5

Sample Output

Case 1: 0.00000000
Case 2: 58.42574374

HINT

 

100%的数据满足Q*n≤10000000,0 ≤x, y, a, b, c≤100, Q≤n。

 

//某出题人是见到了这题以后才出了[Zjoi2014]星系调查

数据及SPJ见http://www.lydsy.com/JudgeOnline/upload/4014.rar
 

我日。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
SPJ居然是错的
正解:偏导
 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

不太会写 本来想练练三分套三分 谁知道不是正解  

三分套三分

 

根据点到直线距离公式
ans=min(Σ(kxi-yi+b)^2 / (k^2 + 1))
这个可以三分套三分算。。。我不会偏导不会证
展开->

 

(k^2x^2-2*k*x*y+y^2+2*b*k*x-2*b*y+b^2)/(k^2+1)

 

预处理出Σxi、Σxi、Σyi、Σxi^2、Σyi^2、Σxiyi
可以O(1)计算答案

 

#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
#define ld long double
using namespace std;
inline int read(){
	int x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
ld x2,y2,sxy,x,y;
int n;
double pi=acos(-1);
inline ld get(ld k,ld b){
	return (k*k*x2+y2+b*b*n-k*2*sxy-b*2*y+b*2*k*x)/(k*k+1);
}
inline ld cal(ld k){
	ld l=-1e9,r=1e9;
	for(int i=1;i<=100;i++){
		ld x1=l+(r-l)/3;ld y1=l+(r-l)/3*2;
		ld t1=get(k,x1);ld t2=get(k,y1);
		if(t1>t2) l=x1;
		else r=y1;
	}
	return get(k,l);
}
int main(){
	//freopen("All.in","r",stdin);
	//freoepn("All.out","w",stdout); 
	int T=read();int ans=0;
	while(T--){
	    ans++;
		x=y=x2=y2=sxy=0;
		n=read();int xx=read();int yy=read();
		int a=read();int b=read();int c=read();
		x+=xx;y+=yy;x2+=xx*xx;y2+=yy*yy;sxy+=xx*yy;
		for(int i=2;i<=n;i++){
			xx=(a*xx*xx+b*xx+c)%107;yy=(a*yy*yy+b*yy+c)%107;
			sxy+=xx*yy;x+=xx;y+=yy;x2+=xx*xx;y2+=yy*yy;
		}
		ld l=-1e9,r=1e9;
		for(int i=1;i<=100;i++){
			ld x1=l+(r-l)/3;ld y1=l+(r-l)/3*2;
			ld t1=cal(x1);ld t2=cal(y1);
			if(t1>t2) l=x1;
			else r=y1;
		}
		printf("Case %d: %.8lf\n",ans,double(cal(l))*pi/n);
	}
	return 0;
}

在BZOJ能过的程序(啊啊啊啊啊啊啊啊啊)

#include <bits/stdc++.h>
using namespace std;
int main(){
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++){
        printf("Case %d: 0\n",i);
    }
    return 0;
}

  

  

posted @ 2018-07-24 15:39  zhangenming  阅读(423)  评论(0编辑  收藏  举报