zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    结构体后面不加 ; 的后果。
    swap的两种错误写法
    rewind和fseek作用分析
    16个get函数的用法。
    枚举的简单使用。
    小知识点
    网线头的做法
    内存和寄存器
    linux下service mongod start启动报错
    appium上下文切换、webview调试以及chromedriver/键盘等报错问题解决
  • 原文地址:https://www.cnblogs.com/liulangye/p/3228024.html
Copyright © 2011-2022 走看看