HDU

来源:互联网 发布:知乎童谣事件文章 编辑:程序博客网 时间:2024/06/06 12:25

题目链接点这里


对于积分我们当然可以直接求原函数,,但是对于我这种数学学渣,,理所当然的不会啊(雾

这时,就需要伟大的simpson来救场了,,hhhh

md,没把x>100的点删了,,wa了一上午


#include<iostream>#include<cstdio>#include<math.h>#include<algorithm>#include<map>#include<set>#include<bitset>#include<stack>#include<queue>#include<string.h>#include<cstring>#include<vector>#include<time.h>#include<stdlib.h>using namespace std;#define INF 0x3f3f3f3f#define INFLL 0x3f3f3f3f3f3f3f3f#define FIN freopen("input.txt","r",stdin);#define mem(x,y) memset(x,y,sizeof(x));typedef unsigned long long ULL;typedef long long LL;#define fuck(x) cout<<x<<endl;#define MX 55#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef pair<pair<int,int>,int> PIII;typedef pair<int,int> PII;int n;double k[MX],a[MX],b[MX];double eps=1e-6;double f(double x,int i){    return k[i]*(x-a[i])*(x-a[i])+b[i]; ;//函数}double f2(double x,int i){    return sqrt(1+2*k[i]*(x-a[i])*2*k[i]*(x-a[i])); ;//函数}double simpson(double l, double r,int i){    double mid = l + (r - l) / 2;    return (f2(l,i) + 4 * f2(mid,i) + f2(r,i)) * (r - l) / 6;}double asr(double l, double r, double eps, double A,int i){    double mid = r + (l - r) / 2;    double L = simpson(l, mid,i), R = simpson(mid, r,i);    if(fabs(L + R - A) <= 15 * eps) return L + R + (L + R - A) / 15.0;    return asr(l, mid, eps / 2, L,i) + asr(mid, r, eps / 2, R,i);}/*求区间[a,b]的定积分,精度为 eps*/double asr(double l, double r, double eps,int i){    return asr(l, r, eps, simpson(l, r,i),i);}struct Point{    double x,y;    Point(double x,double y):x(x),y(y) {}    Point() {}    bool operator <(const Point a)const    {        if(fabs(x-a.x)>eps) return x<a.x;        else return y<a.y;    }    bool operator ==(const Point a)const    {        return fabs(x-a.x)<eps;    }} P[MX*MX];struct Nod{    double l,r;    int x;    Nod(double l, double r,int x):l(l),r(r),x(x) {}};int pcnt;int main(){    FIN;    int cas;    cin>>cas;    while(cas--)    {        pcnt=0;        cin>>n;        k[0]=0,b[0]=100;        for(int i=1; i<=n; i++)scanf("%lf%lf%lf",&k[i],&a[i],&b[i]);        for(int i=0; i<=n; i++)P[pcnt++]=Point(0,f(0,i));        for(int i=0; i<=n; i++)P[pcnt++]=Point(100,f(100,i));        for(int i=0; i<=n; i++)            for(int j=i+1; j<=n; j++)            {                if(k[i]==k[j])                {                    if(a[i]==a[j]) continue;                    double x=-(k[i]*a[i]*a[i]+b[i]-k[j]*a[j]*a[j]-b[j])/(2*k[j]*a[j]-2*k[i]*a[i]);                    if(x>=0&&x<=100)P[pcnt++]=Point(x,f(x,i));                }                else                {                    double aa=k[i]-k[j];                    double bb=2*k[j]*a[j]-2*k[i]*a[i];                    double cc=k[i]*a[i]*a[i]+b[i]-k[j]*a[j]*a[j]-b[j];                    if(fabs(bb*bb-4*aa*cc)>eps&&bb*bb-4*aa*cc<0)continue;                    else                    {                        double x1=(-bb-sqrt(bb*bb-4*aa*cc))/(2*aa);                        double x2=(-bb+sqrt(bb*bb-4*aa*cc))/(2*aa);                        if(fabs(bb*bb-4*aa*cc)<eps)                        {                            if(x1>=0&&x1<=100)P[pcnt++]=Point(x1,f(x1,i));                        }                        else                        {                            if(x1>=0&&x1<=100)P[pcnt++]=Point(x1,f(x1,i));                            if(x2>=0&&x2<=100)P[pcnt++]=Point(x2,f(x2,i));                        }                    }                }            }        sort(P,P+pcnt);        pcnt=unique(P,P+pcnt)-P;        double ans=0;        for(int i=0; i<pcnt-1;)        {            double l=P[i].x;            double mid=(P[i].x+P[i+1].x)/2;            double minn=INF;            int x;            for(int j=0; j<=n; j++)            {                double v=f(mid,j);                if(v<minn)minn=v,x=j;            }            i++;            for(; i<pcnt; i++)if(fabs(P[i].y-f(P[i].x,x))<eps)break;            ans+=asr(l,P[i].x,eps,x);        }        printf("%.2f\n",ans);    }    return 0;}