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;
    }
    

    不淡定了....



  • 相关阅读:
    Linux防火墙管理(iptables)以及开放端口配置
    CSS 样式引入方式、常用选择器以及优先级权重的计算
    初识外边距合并-margin collapsing
    纯CSS实现自适应正方形
    常用正则
    vue 学习记录
    VScode 之快速创建vue模板
    vscode之常用插件
    工具函数
    Axios之配置参数
  • 原文地址:https://www.cnblogs.com/riskyer/p/3225868.html
Copyright © 2011-2022 走看看