zoukankan      html  css  js  c++  java
  • 20191015+

    前言

    • 连第二机房房主也不是了,该高兴还是该呵呵?
    • 板子不会还是硬伤,不会高斯消元的我看到T2都绝望了,YY还写错了……
    • T3特判都打错,佛啦。
    • 咳咳。还有为什么还是这么颓废。
    • 还有%%%文化课巨佬FlashHu

    以上纯属CD。

    T1

    • 先把(a,b)按a单调下降排序,然后将不符合b单调上升的点删除,因为这些点不可能成为答案。
    • 然后将给出的(a,b)抽象成$(frac{1}{a},frac{1}{b})$的点,因为a单调下降b单调上升所以新点集的横坐标单调上升纵坐标单调递减。
    • 直接用栈维护左下凸包,栈内斜率单调递增即可。
    • 时间复杂度$Theta(NlogN)$,空间复杂度$Theta(N)$。
    • 本题精度稍GS,蒟蒻博主的垃圾代码开__float128才能AC……
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #define ll long long
    #define db __float128
    using namespace std;
    typedef pair<pair<int,int>,int> pi;
    int const N=3e5+5;
    db const lar=2e16,eps=-1e-6;
    int n,t;
    pi b[N];
    pair<int,int>a[N];
    vector<int>bs[N];
    int ans[N];
    int stk[N],tp;
    db xp[N],yp[N],xl[N];
    inline int read(){
        int ss(0);char bb(getchar());
        while(bb<48||bb>57)bb=getchar();
        while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
        return ss;
    }
    inline db _max(db x,db y){
        return x>y?x:y;
    }
    inline db _min(db x,db y){
        return x<y?x:y;
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        n=read();
        for(register int i=1;i<=n;++i)b[i].first.first=read(),b[i].first.second=read(),b[i].second=i;
        sort(b+1,b+n+1,[](pi skyh,pi yxs){
            return (skyh.first.first^yxs.first.first)?skyh.first.first>yxs.first.first:skyh.first.second>yxs.first.second;
        });
        for(register int i=1;i<=n;++i)
            if(b[i].first.second>a[t].second)a[++t]=b[i].first,bs[t].push_back(b[i].second);
            else if(b[i].first.first==a[t].first && b[i].first.second==a[t].second)bs[t].push_back(b[i].second);
        n=t,t=0;
        for(register int i=1;i<=n;++i)
            xp[i]=1.0/(db)a[i].first,yp[i]=1.0/(db)a[i].second;
        for(register int i=1;i<=n;++i){
            while(tp>1 && (yp[i]-yp[stk[tp]])/(xp[i]-xp[stk[tp]])<xl[tp])--tp;
            stk[++tp]=i,xl[tp]=(yp[i]-yp[stk[tp-1]])/(xp[i]-xp[stk[tp-1]]);
        }
        /*for(register int i=1;i<=n;++i){
            db minx=lar,maxx=0;
            const db xn=xp[i],yn=yp[i];
            for(register int j=1;j<i;++j)
                maxx=_max(maxx,(xn-xp[j])/(yp[j]-yn));
            for(register int j=i+1;j<=n;++j)
                minx=_min(minx,(xn-xp[j])/(yp[j]-yn));
            //printf("%.15lf %.15lf %d %d
    ",maxx,minx,a[i].first,a[i].second);
            if(minx-maxx>=eps)
                for(auto&j:bs[i])ans[++t]=j;
        }*/
        for(register int i=1;i<=tp;++i)
            for(auto &j:bs[stk[i]])ans[++t]=j;
        sort(ans+1,ans+t+1);
        for(register int i=1;i<=t;++i)printf("%d ",ans[i]);
        puts("");
        return 0;
    }
    View Code

    T2

    • 体验到了板子不会打的绝望。
    • 裸的高斯消元。
    • 不过会高斯消元也得不了多少分因为自己不会得到一个方程的解。
    • 正解直接将目标方程的元消去,最终得到的解就是答案的相反数,因为保证有解所以一定可以消干净。
    • 时间复杂度$Theta(N^3)$,空间复杂度$Theta(N^2)$。
    • 听说不少人觉得读入难,其实吧,只要用一个map映射string就可以了,挺简单的,考试5分钟就打完了。
    #include<cstdio>
    #include<string>
    #include<map>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int const N=203;
    int n,tot;
    double a[N][N],c[N];
    map<string,int>qj;
    bool vis[N];
    inline double _abs(double x){
        return x<0?-x:x;
    }
    inline void _swap(double &x,double &y){
        double z=x;
        x=y,y=z;
        return ;
    }
    inline void Gauss(){
        for(register int i=1,now=1;i<n;now=++i){
            for(register int j=i+1;j<n;++j)
                if(_abs(a[j][i])>_abs(a[now][i]))now=j;
            if(!_abs(a[now][i]))continue;
            double x=a[now][i];
            for(register int j=1;j<=n;++j)
                _swap(a[i][j],a[now][j]),a[i][j]/=x;
            for(register int j=1;j<=n;++j){
                if(j==i)continue;
                x=a[j][i];
                for(register int k=i;k<=n;++k)
                    a[j][k]-=a[i][k]*x;
            }
        }
        return ;
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        scanf("%d",&n);
        string s;
        char ss[5];double zz;
        int xs=1;
        for(register int i=1;i<=n;++i,xs=1)
            while(1){
                scanf("%lf",&zz);zz*=xs;
                cin>>s;
                if(qj[s])a[i][qj[s]]=zz;
                else a[i][qj[s]=++tot]=zz;
                scanf("%s",ss);
                if(ss[0]=='=')xs=-1;
                else if(ss[0]=='H'){
                    scanf("%lf",&c[i]);
                    break;
                }
            }
        n=(tot>n?tot:n)+1;
        for(register int i=1;i<n;++i)a[i][n]=c[i];
        while(1){
            scanf("%lf",&zz),zz*=xs;
            cin>>s;
            if(qj[s])a[n][qj[s]]=zz;
            else a[n][qj[s]=++tot]=zz;
            scanf("%s",ss);
            if(ss[0]=='=')xs=-1;
            else if(ss[0]=='H')break;
        }
        n=max(n,tot+1);
        Gauss();
        a[n][n]?printf("%.1lf",-a[n][n]):puts("0.0");
        return 0;
    }
    View Code

    T3

    • dfs+信仰-1成功30。
    • 首先时间显然随k的增加单调不降,所以可以二分答案。
    • 因为选出的k个人的位置在t时刻后的相对位置不能发生改变,所以题意可以转化成最长上升子序列。
    • 求出时间后,我们考虑如何构造字典序最小的最优解。
    • LIS可以看成一棵树,每次转移相当于新加一个叶节点。
    • 对于两个深度都为k的节点x,y,设lca(x,y)=fa。
    • 那么如果x到fa路径上的最小编号小于y到fa路径上的最小编号,那么深度为k的解x比y优。
    • 于是我们可以求出任意深度的最优解,但这个最优解的转移位置任意,而LIS的解必须保证权值单调上升。
    • 我们可以对于每个深度开一棵动态开点线段树,维护前缀最优解就可以正确转移了。
    • 由于博主太垃圾不会树状数组所以无论是LIS还是构造字典序最小的解都用的线段树而且不是zkw,所以常数巨大会T。
    • 所以博主用了一个优化lca的常用方法。
    • 可能大家不是很在意倍增lca的log,但事实上直接设一个极值比如log100000的做法常数很大。
    • 优化很简单,预处理出1~n每个数的log值,进行倍增时只倍增到log[dep]。进行这种优化后博主可以通过本题。
    • 时间复杂度$Theta(NlogNlogT+Nlog^2N)$,空间复杂度$Theta(NlogN)$。
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    #define L tr[k].lc
    #define R tr[k].rc
    #define LC Tr[k].ls
    #define RC Tr[k].rs
    using namespace std;
    int const N=1e5+5,M=86400;
    int n,k;
    struct node{
        int a,id;
        ll c;
    }q[N];
    int p[N];
    pair<long double,int>b[N];
    struct Ljj{
        int lc,rc,w;
    }tr[N<<3];
    struct S_Tree{
        int ls,rs,val,f;
    }Tr[N*100];
    int tot,rt[N],Log[N],dep[N],f[N][18],mx[N][18];
    int ans[N];
    inline ll read(){
        ll ss(0),pp(1);char bb(getchar());
        for(;bb<48||bb>57;bb=getchar())if(bb=='-')pp=-1;
        while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
        return ss*pp;
    }
    inline void _swap(int &x,int &y){
        int z=x;
        x=y,y=z;
        return ;
    }
    inline int min(int x,int y){
        return x<y?x:y;
    }
    inline int max(int x,int y){
        return x>y?x:y;
    }
    void build(int x,int y,int k){
        L=x,R=y;
        if(x==y)return ;
        int mid=x+y>>1;
        return build(x,mid,k<<1),build(mid+1,y,k<<1|1);
    }
    void clear(int k){
        if(!L||!tr[k].w)return ;
        tr[k].w=0;
        return clear(k<<1),clear(k<<1|1);
    }
    int ask(int x,int y,int k){
        if(L>=x&&R<=y)return tr[k].w;
        int mid=L+R>>1,as=0;
        if(x<=mid)as=ask(x,y,k<<1);
        if(y>mid)as=max(as,ask(x,y,k<<1|1));
        return as;
    }
    void add(int x,int y,int k){
        if(L==R){tr[k].w=max(tr[k].w,y);return ;}
        int mid=L+R>>1;
        if(x<=mid)add(x,y,k<<1);
        else add(x,y,k<<1|1);
        tr[k].w=max(tr[k<<1].w,tr[k<<1|1].w);
        return ;
    }
    inline bool check(int x){
        clear(1);
        for(register int i=1;i<=n;++i)b[i].first=0.5*x*x*q[i].a+q[i].c,b[i].second=i;
        sort(b+1,b+n+1);
        int now=0;
        b[0].first=b[1].first+1;
        for(register int i=1;i<=n;++i)
            p[b[i].second]=now=now+(b[i].first!=b[i-1].first);
        for(register int i=1,z;i<=n;++i){
            z=0;
            if(p[i]!=1)z=ask(1,p[i]-1,1);
            add(p[i],++z,1);
            if(z>=k)return 1;
        }
        return 0;
    }
    inline int getmin(int x,int y){
        if(!x||!y)return x+y;
        if(x==y)return x;
        int xm=x,ym=y,xx=x,yy=y;
        for(register int i=Log[dep[x]];~i;--i)
            if(f[x][i]^f[y][i]){
                xm=min(xm,mx[x][i]),ym=min(ym,mx[y][i]);
                x=f[x][i],y=f[y][i];
            }
        return xm<ym?xx:yy;
    }
    inline void down(int k){
        if(!LC)LC=++tot;
        if(!RC)RC=++tot;
        int x=Tr[k].f;
        Tr[k].f=0;
        Tr[LC].val=getmin(Tr[LC].val,x),Tr[LC].f=getmin(Tr[LC].f,x);
        Tr[RC].val=getmin(Tr[RC].val,x),Tr[RC].f=getmin(Tr[RC].f,x);
        return ;
    }
    int Query(int l,int r,int x,int k){
        if(!k)return 0;
        if(r<=x)return Tr[k].val;
        if(Tr[k].f&&l^r)down(k);
        int mid=l+r>>1,zz=Query(l,mid,x,LC);
        if(x>mid)zz=getmin(zz,Query(mid+1,r,x,RC));
        return zz;
    }
    void Insert(int l,int r,int x,int y,int &k){
        if(!k)k=++tot;
        if(l>=x){
            Tr[k].val=getmin(y,Tr[k].val),Tr[k].f=getmin(y,Tr[k].f);
            return ;
        }
        if(Tr[k].f&&l^r)down(k);
        int mid=l+r>>1;
        if(x<=mid)Insert(l,mid,x,y,LC);
        Insert(mid+1,r,x,y,RC);
        Tr[k].val=getmin(Tr[LC].val,Tr[RC].val);
        return ;
    }
    int main(){
        //freopen("1.in","r",stdin);
        //freopen("1.out","w",stdout);
        n=read(),k=read();
        Log[0]=-1;
        for(register int i=1;i<=n;++i)q[i].c=read(),q[i].a=read(),q[i].id=i,Log[i]=Log[i>>1]+1;
        sort(q+1,q+n+1,[](node skyh,node yxs){
            return skyh.c<yxs.c;
        });
        build(1,n,1);
        int l=0,r=M;
        while(l<r){
            int mid=l+r+1>>1;
            if(check(mid))l=mid;
            else r=mid-1;
        }
        printf("%d
    ",l);
        ++k;
        if(check(l))return puts("-1"),0;
        clear(1),memset(mx,0x3f,sizeof(mx));
        for(register int i=1;i<=n;++i)b[i].first=0.5*l*l*q[i].a+q[i].c,b[i].second=i;
        sort(b+1,b+n+1);
        int now=0;
        b[0].first=b[1].first+1;
        for(register int i=1;i<=n;++i)
            p[b[i].second]=now=now+(b[i].first!=b[i-1].first);
        for(register int i=1,z,x,y;i<=n;++i){
            z=0,y=q[i].id;
            if(p[i]!=1)z=ask(1,p[i]-1,1);
            add(p[i],z+1,1);
            if(p[i]!=1)f[y][0]=Query(1,n,p[i]-1,rt[z]);
            mx[y][0]=min(y,f[y][0]),dep[y]=z+1;
            for(register int j=0;j<Log[z];++j)
                f[y][j+1]=f[f[y][j]][j],mx[y][j+1]=min(mx[y][j],mx[f[y][j]][j]);
            Insert(1,n,p[i],y,rt[z+1]);
        }
        now=Query(1,n,n,rt[k-1]);
        for(register int i=1;i<k;++i)
            ans[i]=now,now=f[now][0];
        sort(ans+1,ans+k);
        for(register int i=1;i<k;++i)
            printf("%d
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    智能推荐算法演变及学习笔记(三):CTR预估模型综述
    从中国农业银行“雅典娜杯”数据挖掘大赛看金融行业数据分析与建模方法
    智能推荐算法演变及学习笔记(二):基于图模型的智能推荐(含知识图谱/图神经网络)
    (设计模式专题3)模板方法模式
    (设计模式专题2)策略模式
    (设计模式专题1)为什么要使用设计模式?
    关于macOS上常用操作命令(持续更新)
    记录下关于RabbitMQ常用知识点(持续更新)
    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
    SpringCloud教程二:Ribbon(Finchley版)
  • 原文地址:https://www.cnblogs.com/remarkable/p/11687010.html
Copyright © 2011-2022 走看看