zoukankan      html  css  js  c++  java
  • APIO2015泛做

    可以在UOJ上提交可以在bzoj上提交(权限)

    A. Bali Sculptures

    对于前72%的数据,按位考虑,然后跑一点沙茶dp就行了。

    dp:用f[x][y]表示前x位分为y段是否满足条件。

    对于最后29%的数据,我们改一下dp方程。

    dp:用f[x]表示前x位满足条件至少要分几段。

    结论:傻逼题

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <math.h>
    #include <limits>
    #include <set>
    #include <map>
    using namespace std;
    #define SZ 2066
    typedef long long ll;
    int n,a,b,yy[SZ];
    #define S 50
    ll inn=0,sum[SZ]; 
    bool dp2[SZ][SZ];
    bool chk2()
    {
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++) dp2[i][j]=0;
        dp2[0][0]=1;
        for(int i=0;i<n;i++) //分i段 
        {
            for(int j=0;j<n;j++)
            {
                if(!dp2[i][j]) continue;
                for(int k=j+1;k<=n;k++)
                {
                    if(((sum[k]-sum[j])|inn)==inn) dp2[i+1][k]=1;
                }
            }
        }
        for(int i=a;i<=b;i++) if(dp2[i][n]) return 1;
        return 0;
    }
    int dp1[SZ];
    const int inf=1000000000;
    bool chk1()
    {
        dp1[0]=0;
        for(int i=1;i<=n;i++) dp1[i]=inf;
        for(int j=0;j<n;j++)
        {
            if(dp1[j]==inf) continue;
            for(int k=j+1;k<=n;k++)
            {
                if(((sum[k]-sum[j])|inn)==inn) dp1[k]=min(dp1[k],dp1[j]+1);
            }
        }
        return dp1[n]<=b;
    }
    int main()
    {
        scanf("%d%d%d",&n,&a,&b);
        for(int i=1;i<=n;i++) scanf("%d",yy+i), sum[i]=sum[i-1]+yy[i];
        inn=(1LL<<S)-1;
        for(int i=S;i>=1;i--)
        {
            inn^=1LL<<(i-1);
            if(!((a==1)?chk1():chk2())) inn^=1LL<<(i-1);
        }
        printf("%lld
    ",inn);
    }

    B. Jakarta Skyscrapers

    据说可以卡时过?然而UOJ有hack啊根本过不了

    等知道正解了再来补

    C. Palembang Bridges

    一座桥的时候,容易发现要建在中位数的地方。

    两座桥的时候,按照每个人的家和办公室位置和排序后,一定存在一个分割点使得前缀都走左边的桥,后缀都走右边的桥,这似乎挺显然的。

    然后离散完随手树状数组+二分维护一下中位数啥的即可。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <math.h>
    #include <limits>
    #include <set>
    #include <map>
    using namespace std;
    #define SZ 666666
    typedef long long ll;
    int K,n,as[SZ],bs[SZ],ap[SZ];
    ll ans=0;
    int Abs(int x) {return (x>=0)?x:-x;}
    ll a_1()
    {
        ll aa=0; int nn=0;
        for(int i=1;i<=n;i++) ap[++nn]=as[i];
        for(int i=1;i<=n;i++) ap[++nn]=bs[i];
        sort(ap+1,ap+1+nn);
        int md=ap[(nn+1)>>1];
        for(int i=1;i<=nn;i++) aa+=Abs(ap[i]-md);
        return aa;
    }
    typedef pair<int,int> pii;
    pii zs[SZ];
    bool cmp(pii a,pii b) {return a.first+a.second<b.first+b.second;}
    #define SN 233333
    struct Bits
    {
    ll bits[SZ];
    ll sum(int x)
    {
        ll ans=0;
        for(;x>=1;x-=x&-x) ans+=bits[x];
        return ans;
    }
    ll sum(int l,int r) {return sum(r)-sum(l-1);}
    void edit(int x,ll y)
    {
        for(;x<=SN;x+=x&-x) bits[x]+=y;
    }
    void clr() {for(int i=1;i<=SN;i++) bits[i]=0;}
    }B1,B2;
    ll zd[SZ],fd[SZ];
    #define ls(x) (lower_bound(ap+1,ap+1+nn,x)-ap)
    ll a_2()
    {
        ll aa=20000000000000000LL; int nn=0;
        for(int i=1;i<=n;i++) ap[++nn]=as[i];
        for(int i=1;i<=n;i++) ap[++nn]=bs[i];
        sort(ap+1,ap+1+nn);
        nn=unique(ap+1,ap+1+nn)-ap-1;
        for(int i=1;i<=n;i++) zs[i].first=as[i], zs[i].second=bs[i];
        sort(zs+1,zs+1+n,cmp);
        B1.clr(); B2.clr();
        for(int i=1;i<=n;i++)
        {
            int A=ls(zs[i].first),B=ls(zs[i].second);
            B1.edit(A,1);
            B2.edit(A,zs[i].first);
            B1.edit(B,1);
            B2.edit(B,zs[i].second);
            int l=0,r=nn;
            while(l<r)
            {
                int mid=(l+r)>>1;
                int s=B1.sum(mid);
                if(s<i) l=mid+1; else r=mid;
            }
            int mn=ap[l];
            ll cans=B1.sum(l)*mn-B2.sum(l)+B2.sum(l,nn)-B1.sum(l,nn)*mn;
            zd[i]=cans;
        }
        B1.clr(); B2.clr();
        for(int i=n;i>=1;i--)
        {
            int A=ls(zs[i].first),B=ls(zs[i].second);
            B1.edit(A,1);
            B2.edit(A,zs[i].first);
            B1.edit(B,1);
            B2.edit(B,zs[i].second);
            int l=0,r=nn;
            while(l<r)
            {
                int mid=l+r>>1;
                int s=B1.sum(mid);
                if(s<n+1-i) l=mid+1; else r=mid;
            }
            int mn=ap[l];
            ll cans=B1.sum(l)*mn-B2.sum(l)+B2.sum(l,nn)-B1.sum(l,nn)*mn;
            fd[i]=cans;
        }
        for(int i=1;i<=n+1;i++) aa=min(aa,zd[i-1]+fd[i]);
        return aa;
    }
    int main()
    {
        int N; scanf("%d%d",&K,&N);
        for(int i=1;i<=N;i++)
        {
            char a[3],c[3]; int b,d;
            scanf("%s%d%s%d",a,&b,c,&d);
            if(a[0]==c[0])
            {
                ans+=Abs(b-d);
                continue;
            }
            ++n; as[n]=b; bs[n]=d;
        }
        if(K==1) printf("%lld
    ",a_1()+ans+n);
        else printf("%lld
    ",a_2()+ans+n);
    }
  • 相关阅读:
    vue proxy代理理解
    css样式鲜为人知的属性
    vue中实现元素选中互斥
    站长统计加载慢解决方法
    微信图片预览接口
    移动端兼容问题
    请求头和响应头
    清除缓存方法
    屏幕适配及rem
    清除多个定时器
  • 原文地址:https://www.cnblogs.com/zzqsblog/p/5433029.html
Copyright © 2011-2022 走看看