hdu 4631 Sad Love Story

http://acm.hdu.edu.cn/showproblem.php?pid=4631

没想到这道题需要用“平均时间复杂度” 计算   一直没有想到解法  因为不符考虑了最坏情况的理念

方法一:

每加一个点 就找x值和它接近的 有可能更新最小距离的点进行判断更新 运行的相当的快 无语

方法二:

每求出所有点的最近点对 假如说是p[i],p[j](i<j) 那么在j之后加上的点不影响最小距离

递归j前面的所有点就可以了

由于自己的 求最近点对算法 写的相当烂 所有跑的相当慢,勉强过

代码1和代码2:

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<string>

#include<cstring>

#include<cmath>

#include<set>

#include<vector>

using namespace std;



typedef long long ll;

typedef pair<double,double>ppd;

const double PI = acos(-1.);

const double eps = (1e-9);

const int N=1000010;

vector<int>vt[N];

int main()

{

    //freopen("data.in","r",stdin);

    int T;

    scanf("%d",&T);

    while(T--)

    {

        for(int i=0;i<N;++i)

        vt[i].clear();

        int n;

        scanf("%d",&n);

        int A1,B1,C1,A2,B2,C2;

        cin>>A1>>B1>>C1;

        cin>>A2>>B2>>C2;

        int x=0,y=0;

        ll ans=0;

        ll tmp=(ll)(1e13);

        for(int i=1;i<=n;++i)

        {

            x=((ll)A1*x+B1)%C1;

            y=((ll)A2*y+B2)%C2;

            for(int i=0;x+i<=1000000;++i)

            {

                ll x1=(ll)i*i;

                if(x1>=tmp)

                break;

                for(unsigned int j=0;j<vt[x+i].size();++j)

                tmp=min(tmp,x1+(ll)(y-vt[x+i][j])*(y-vt[x+i][j]));

            }

            for(int i=-1;x+i>=0;--i)

            {

                ll x1=(ll)i*i;

                if(x1>=tmp)

                break;

                for(unsigned int j=0;j<vt[x+i].size();++j)

                tmp=min(tmp,x1+(ll)(y-vt[x+i][j])*(y-vt[x+i][j]));

            }

            vt[x].push_back(y);

            if(tmp!=(ll)(1e13))

            ans+=tmp;

        }

        cout<<ans<<endl;

    }

    return 0;

}



#include<iostream>

#include<cstdio>

#include<algorithm>

#include<string>

#include<cstring>

#include<cmath>

#include<set>

#include<vector>

using namespace std;



typedef long long ll;

typedef pair<int,int>pp;

const double PI = acos(-1.);

const double eps = (1e-9);

const int N=1000010;

pp p[N];

struct node

{

    int x,y;

    int index;

}a[N],b[N];

ll dist(const node &a,const node &b)

{

    return (ll)(a.x-b.x)*(a.x-b.x)

    +(ll)(a.y-b.y)*(a.y-b.y);

}

bool cmpx(const node &a,const node &b)

{

    return a.x<b.x;

}

bool cmpy(const node &a,const node &b)

{

    return a.y<b.y;

}

ll dfs(int l,int r,int &k)

{

    if(r-l==1)

    {k=max(a[l].index,a[r].index);return dist(a[l],a[r]);}

    int m=(l+r)>>1;

    int k1,k2;

    ll d;

    ll d1=dfs(l,m,k1);

    ll d2=dfs(m,r,k2);

    if(d1<d2) {d=d1;k=k1;}

    else {d=d2;k=k2;}

    int ln=0,M=(int)(sqrt(1.0*d));

    for(int i=m+1;i<=r&&a[i].x-a[m].x<=M;++i)

    {b[ln]=a[i];++ln;}

    for(int i=m-1;i>=l&&a[m].x-a[i].x<=M;--i)

    {b[ln]=a[i];++ln;}

    sort(b,b+ln,cmpy);

    for(int i=0;i<ln;++i)

    for(int j=1;j<=7&&i+j<ln;++j)

    if(dist(b[i],b[i+j])<d)

    {d=dist(b[i],b[i+j]);k=max(b[i].index,b[i+j].index);}

    return d;

}

ll solve(int n)

{

    ll ans=0;

    int r=n;

    while(r>=2)

    {

        for(int i=1;i<=r;++i)

        {a[i].x=p[i].first;a[i].y=p[i].second;a[i].index=i;}

        sort(a+1,a+r+1,cmpx);

        int k;

        ll tmp=dfs(1,r,k);

        ans+=tmp*(r-k+1);

        r=k-1;

    }

    return ans;

}

int main()

{

    //freopen("data.in","r",stdin);

    int T;

    scanf("%d",&T);

    while(T--)

    {

        int n;

        scanf("%d",&n);

        int A1,B1,C1,A2,B2,C2;

        scanf("%d %d %d",&A1,&B1,&C1);

        scanf("%d %d %d",&A2,&B2,&C2);

        p[0].first=0,p[0].second=0;

        for(int i=1;i<=n;++i)

        {

            p[i].first=((ll)A1*p[i-1].first+B1)%C1;

            p[i].second=((ll)A2*p[i-1].second+B2)%C2;

        }

        cout<<solve(n)<<endl;

    }

    return 0;

}

 

 

 

 

你可能感兴趣的:(love)