4014: [FJOI2014]病毒防护带
Time Limit: 20 Sec Memory Limit: 512 MBSec Special JudgeSubmit: 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
2
0 0
0 0 1
3
1 2
3 4 5
Sample Output
Case 1: 0.00000000
Case 2: 58.42574374
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 ",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 ",i); } return 0; }