zoukankan      html  css  js  c++  java
  • HDU/杭电2013多校第三场解题报告

    今天悲剧了,各种被虐啊,还是太年轻了哭

    Crime

    这道题目给的时间好长,第一次就想到了暴力,结果华丽丽的TLE了。

    后来找了一下,发现前24个是1, 2, 6, 12, 72, 72, 864, 1728, 13824, 22032, 555264, 476928, 17625600, 29599488, 321115392, 805146624, 46097049600, 36481536000, 2754120268800, 3661604352000, 83905105305600, 192859121664000, 20092043520000000, 15074060547686400。这样我们就需要找到递推的式子。可是怎么也推不出。请路过的大神指教。。。

    JZPTREE

    这道题目是我看的,题目挺好懂的,就是数据量太大。不知道怎么写,最后想尽办法也只能压缩到十二亿。果断不行,怎么优化呢?

    Jinkeloid

    深坑....

    The Unsolvable Problem

    这道题目是过的最多的了题目了。就是that a + b = n and [a, b] is as large as possible. [a, b] denote the least common multiplier of a, b.这样的话就直接求就行了。是偶数的话变成前后值,否则前后判:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <string.h>
    #include <map>
    #include <vector>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <stack>
    using namespace std;
    
    int main()
    {
        int t;
        __int64 n;
        cin>>t;
        while(t--)
        {
            cin>>n;
            if(n==2)
            {
                cout<<1<<endl;
                continue;
            }
            if(n%2==1)
            {
                cout<<(n/2)*(n/2+1)<<endl;
            }
            else
            {
                if((n/2)%2==0)
                {
                    cout<<(n/2-1)*(n/2+1)<<endl;
                }
                else
                {
                    cout<<(n/2-2)*(n/2+2)<<endl;
                }
            }
        }
        return 0;
    }
    

    Pieces

    这是经次于上一道出的最多的题了。就是把一个字符串变空。用的方法就是每次去一个回文串,直到取空。唯一的要求就是最后操作的次数要最小。这道题目需要考虑每次操作之后对后续的影响,不能直接求最长的回文串,可能后面就会因为这次操作而增加了操作次数;

    Burning

    一道几何题目,特判,精度...

    Sad Love Story

    这道题目T到死了。先用最近点对的方法求了,TTT。后来有交KD-tree的,结果也T了,这不科学啊,20S额。这:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <string.h>
    #include <map>
    #include <vector>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <stack>
    using namespace std;
    // 分治算法求最近点对
    
    struct point
    {
        __int64 x , y;
    } p[500005],pp[500005];
    
    __int64 a[500005];    //保存筛选的坐标点的索引
    
    __int64 cmpx(const point &a , const point &b)
    {
        return a.x < b.x;
    }
    __int64 cmpy(__int64 a , __int64 b)    //这里用的是下标索引
    {
        return p[a].y < p[b].y;
    }
    inline __int64 dis(point &a , point &b)
    {
        return  (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
    }
    inline __int64 min(__int64 a , __int64 b)
    {
        return a < b ? a : b;
    }
    __int64 closest(__int64 low , __int64 high)
    {
        if(low + 1 == high)
            return dis(p[low] , p[high]);
        if(low + 2 == high)
            return min(dis(p[low] , p[high]) , min( dis(p[low] , p[low+1]) , dis(p[low+1] , p[high]) ));
        __int64 mid = (low + high)>>1;//求中点
        __int64 ans = min( closest(low , mid) , closest(mid + 1 , high) );    //分治法进行递归求解
        __int64 i , j , cnt = 0;
        for(i = low ; i <= high ; ++i)   //把x坐标在p[mid].x-ans~p[mid].x+ans范围内的点取出来
        {
            if(p[i].x >= p[mid].x - ans && p[i].x <= p[mid].x + ans)
                a[cnt++] = i;       //保存的是下标索引
        }
        sort(a,a + cnt,cmpy);   //按y坐标进行升序排序
        for(i = 0 ; i < cnt ; ++i)
        {
            for(j = i+1 ; j < cnt ; ++j)
            {
                if(p[a[j]].y - p[a[i]].y >= ans)   //注意下标索引
                    break;
                ans = min(ans , dis(p[a[i]] , p[a[j]]));
            }
        }
        return ans;
    }
    int main()
    {
        __int64 t;
        scanf("%I64d", &t);
        __int64 n, ax, bx,cx,ay,by,cy;
        __int64 ans = 0;
        while(t--)
        {
            ans = 0;
            scanf("%I64d", &n);
            scanf("%I64d%I64d%I64d%I64d%I64d%I64d", &ax,&bx,&cx,&ay,&by,&cy);
            for(int i = 0; i < n; ++i)
            {
                if(i==0)
                {
                    pp[i].x = (0*ax+bx)%cx;
                    pp[i].y = (0*ay+by)%cy;
                }
                else
                {
                    pp[i].x = (pp[i-1].x*ax+bx)%cx;
                    pp[i].y = (pp[i-1].y*ay+by)%cy;
                    int tp = i;
                    for(int kp = 0; kp <= i; ++kp)
                    {
                        p[kp].x = pp[kp].x;
                        p[kp].y = pp[kp].y;
                    }
                    sort(p , p+tp+1 , cmpx);
                    ans += closest(0 , tp);
                }
            }
            printf("%I64d
    ", ans);
        }
        return 0;
    }

    KD-tree

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define D 2
    #define N 500010
    const int inf=1000000001;
    const long long Inf=1ll*inf*inf;
    struct kdnode
    {
        int x[D];
        int split;
        int l,r,p;
    } kdtree[N],q[N];
    bool operator==(const kdnode &a,const kdnode &b)
    {
        for(int i=0; i<D; i++)
        {
            if(a.x[i]!=b.x[i])return false;
        }
        return true;
    }
    double avg[D],var[D];
    int n;
    void calAvg(int l,int r)
    {
        for(int i=0; i<D; i++)avg[i]=0;
        for(int i=l; i<=r; i++)
            for(int j=0; j<D; j++)
                avg[j]+=1.0*kdtree[i].x[j]/(r-l+1);
    }
    void calVar(int l,int r)
    {
        for(int i=0; i<D; i++)var[i]=0;
        for(int i=l; i<=r; i++)
            for(int j=0; j<D; j++)
                var[j]+=1.0*(kdtree[i].x[j]-avg[j])/n*(kdtree[i].x[j]-avg[j]);
    }
    int splitD;
    double maxVar;
    bool cmp(kdnode a,kdnode b)
    {
        return a.x[splitD]<b.x[splitD];
    }
    int construct(int p,int l,int r)
    {
        if(r<l)return -1;
        int root=(l+r)/2;
        calAvg(l,r);
        calVar(l,r);
        maxVar=-1.0;
        for(int i=0; i<D; i++)
            if(var[i]>maxVar)
                maxVar=var[i],splitD=i;
        sort(kdtree+l,kdtree+r+1,cmp);
        kdtree[root].split=splitD;
        kdtree[root].l=construct(root,l,root-1);
        kdtree[root].r=construct(root,root+1,r);
        kdtree[root].p=p;
        return root;
    }
    int Find(int root,kdnode x)
    {
        if(root==-1)return -1;
        if(x==kdtree[root])
        {
            return root;
        }
        int d=kdtree[root].split;
        if(x.x[d]>kdtree[root].x[d])
        {
            return Find(kdtree[root].r,x);
        }
        else if(x.x[d]<kdtree[root].x[d])
        {
            return Find(kdtree[root].l,x);
        }
        else
        {
            int l=Find(kdtree[root].l,x);
            int r=Find(kdtree[root].r,x);
            return (l==-1?r:l);
        }
    }
    int FindMin(int root,int d)
    {
        int ret=root;
        if(kdtree[root].l!=-1)
        {
            int v=FindMin(kdtree[root].l,d);
            if(kdtree[ret].x[d]>kdtree[v].x[d])
                ret=v;
        }
        if(kdtree[root].r!=-1)
        {
            int v=FindMin(kdtree[root].r,d);
            if(kdtree[ret].x[d]>kdtree[v].x[d])
                ret=v;
        }
        return ret;
    }
    int FindMax(int root,int d)
    {
        int ret=root;
        if(kdtree[root].l!=-1)
        {
            int v=FindMax(kdtree[root].l,d);
            if(kdtree[ret].x[d]<kdtree[v].x[d])
                ret=v;
        }
        if(kdtree[root].r!=-1)
        {
            int v=FindMax(kdtree[root].r,d);
            if(kdtree[ret].x[d]<kdtree[v].x[d])
                ret=v;
        }
        return ret;
    }
    void DeleteNode(int v)
    {
        int p=kdtree[v].p;
        kdtree[v].p=-1;
        if(kdtree[p].l==v)
            kdtree[p].l=-1;
        else
            kdtree[p].r=-1;
    }
    void Remove(int root,kdnode x)
    {
        int pos=Find(root,x);
        if(kdtree[pos].l==-1&&kdtree[pos].r==-1)
        {
            DeleteNode(pos);
        }
        else if(kdtree[pos].l==-1)
        {
            int alt=FindMin(kdtree[pos].r,kdtree[pos].split);
            for(int i=0; i<D; i++)kdtree[pos].x[i]=kdtree[alt].x[i];
            Remove(alt,kdtree[alt]);
        }
        else
        {
            int alt=FindMax(kdtree[pos].l,kdtree[pos].split);
            for(int i=0; i<D; i++)kdtree[pos].x[i]=kdtree[alt].x[i];
            Remove(alt,kdtree[alt]);
        }
    }
    void Insert(int root,int x)
    {
        int d=kdtree[root].split;
        if(kdtree[root].x[d]<kdtree[x].x[d])
        {
            if(kdtree[root].r==-1)
            {
                kdtree[root].r=x;
                kdtree[x].p=root;
            }
            else Insert(kdtree[root].r,x);
        }
        else
        {
            if(kdtree[root].l==-1)
            {
                kdtree[root].l=x;
                kdtree[x].p=root;
            }
            else Insert(kdtree[root].l,x);
        }
    }
    void Add(int root,kdnode x)
    {
        int pos=n;
        kdtree[n++]=x;
        Insert(root,pos);
    }
    
    long long dist(kdnode a,kdnode b)
    {
        long long ret=0;
        for(int i=0; i<D; i++)
        {
            ret+=1ll*(a.x[i]-b.x[i])*(a.x[i]-b.x[i]);
        }
        return ret;
    }
    long long query(int root,kdnode x)
    {
        if(root==-1)return Inf;
        int d=kdtree[root].split;
        long long ret;
        if(x.x[d]<kdtree[root].x[d])
        {
            ret=query(kdtree[root].l,x);
            double dd=1.0*x.x[d]+sqrt(1.0*ret);
            if(dd>=1.0*kdtree[root].x[d])
            {
                ret=min(ret,query(kdtree[root].r,x));
            }
        }
        else if(x.x[d]>kdtree[root].x[d])
        {
            ret=query(kdtree[root].r,x);
            double dd=1.0*x.x[d]-sqrt(1.0*ret);
            if(dd<=1.0*kdtree[root].x[d])
            {
                ret=min(ret,query(kdtree[root].l,x));
            }
        }
        else
        {
            ret=query(kdtree[root].l,x);
            ret=min(ret,query(kdtree[root].r,x));
        }
        ret=min(ret,dist(kdtree[root],x));
        return ret;
    }
    
    int main()
    {
       // freopen("in","w",stdout);
        int t;
        long long px,py;
        long long  ax,bx,cx,ay,by,cy;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            px=py=0;
            scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&ax,&bx,&cx,&ay,&by,&cy);
            px=(ax*px+bx)%cx;
            py=(ay*py+by)%cy;
           // puts("fdsf");
            for(int i=0; i<1; i++)
            {
                kdtree[i].split=0;
                kdtree[i].p=kdtree[i].l=kdtree[i].r=-1;
                kdtree[i].x[0]=px;
                kdtree[i].x[1]=py;
                q[i]=kdtree[i];
              //  cout<<px<<" "<<py<<endl;
            }
            int root=construct(-1,0,0);
    
                px=(ax*px+bx)%cx;
                py=(ay*py+by)%cy;
                q[1].split=0;
                q[1].p=q[1].l=q[1].r=-1;
                q[1].x[0]=px;
                q[1].x[1]=py;
            //     cout<<px<<" "<<py<<endl;
                long long mindis=query(root,q[1]);
                long long ans=mindis;
                  Add(root,q[1]);
               // cout<<mindis<<endl;
               // printf("%I64d
    ",mindis);
            int m=n;
            for(int i=3; i<m; i++)
            {
               // printf("%d %d
    ",i,n);
                px=(ax*px+bx)%cx;
                py=(ay*py+by)%cy;
                q[i].split=0;
                q[i].p=q[i].l=q[i].r=-1;
                q[i].x[0]=px;
                q[i].x[1]=py;
                mindis=min(mindis,query(root,q[i]));
                if(mindis==0LL)break;
                ans+=mindis;
                Add(root,q[i]);
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    

    不淡定了....



  • 相关阅读:
    Postgresql HStore 插件试用小结
    postgres-xl 安装与部署 【异常处理】ERROR: could not open file (null)/STDIN_***_0 for write, No such file or directory
    GPDB 5.x PSQL Quick Reference
    postgresql 数据库schema 复制
    hive 打印日志
    gp与 pg 查询进程
    jquery table 发送两次请求 解惑
    python 字符串拼接效率打脸帖
    postgresql 日期类型处理实践
    IBM Rational Rose软件下载以及全破解方法
  • 原文地址:https://www.cnblogs.com/riskyer/p/3225868.html
Copyright © 2011-2022 走看看