• 20160819训练记录


    T1

    给定一个序列 ,在第i时刻a_i位置右边插入一个数i 求最后的序列

    【题解】倒着做。。插入的位置是左边有a_i空格的位置 用线段树维护一下单点修改

    线段树写的优雅一点

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int p,f[4444444],g[4444444],ans[4444444];
    int find(int i,int l,int r,int x){
        f[i]--;
        if(l==r)return i-p+1;
        if(f[i<<1]>=x)return find((i<<1),l,(l+r)/2,x);
        else return find((i<<1|1),(l+r)/2+1,r,x-f[i<<1]);
    } 
    #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
    
    int main(){
        FO(sequence);
        int n;scanf("%d",&n); 
        for(int i=1;i<=n;i++)scanf("%d",&g[i]);
        for(p=1;p<n;p<<=1)cerr<<p;
        for(int i=p;i<p+p;i++)f[i]=1;
        for(int i=p-1;i>=1;i--)f[i]=f[i*2]+f[i*2+1];
        cerr<<f[1]<<endl;
        for(int i=n;i>=1;i--)ans[find(1,1,p,g[i]+1)]=i;
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);    
    }

    T2

    0/1背包

    但是image

    额 对于这个问题 ,我们可以先找到前20个物品对于每个重量的最大价值

    然后求出后20个的 然后二分一下两个体积合并的最优值。。记得long long

    #include<map>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,_p;
    typedef long long ll;
    ll m,ans,w[44],v[44],max_val[1200666];
    
    struct data{
        ll w,v;
    }pii[1233333];
    inline bool cmp(const data&a,const data&b){
        return a.w<b.w||(a.w==b.w&&a.v<b.v);
    }
    inline ll max(ll a,ll b){
        return a>b?a:b;
    }
    int binary_search(ll x){
        int l=1,r=_p,mid=1,ans=1;
        while(l<=r){
            mid=(l+r)/2;
            if(pii[mid].w<=x){
                ans=mid;
                l=mid+1;
            } else r=mid-1;
        }
        return ans;
    }
    int main(){
        freopen("pack.in","r",stdin);
        freopen("pack.out","w",stdout);
        scanf("%d %I64d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%I64d %I64d",&w[i],&v[i]);
        
        int hf=(1<<(n/2)),_hf=0;
        for(int i=0;i<hf;i++){
            ll ww=0,vv=0;
            for(int k=1;k<=n/2;k++)if(i&(1<<(k-1)))ww+=w[k],vv+=v[k];
            if(ww<=m){
                data t=(data){ww,vv};pii[++_hf]=t;
            }
        }
        sort(pii+1,pii+_hf+1,cmp);
        for(int i=1;i<=_hf;i++){
            if(pii[i].w!=pii[i+1].w)pii[++_p]=(data)pii[i];
        
        }
        for(int i=1;i<=_p;i++)max_val[i]=max(max_val[i-1],pii[i].v);
        //for(int i=1;i<=_p;i++)cout<<pii[i].w<<' '<<pii[i].v<<endl; 
        int fff=(1<<(n/2+(n&1)));
        for(int i=0;i<fff;i++){
            ll ww=0,vv=0;
            for(int k=1;k<=n/2+(n&1);k++)if(i&(1<<(k-1)))ww+=w[k+(n>>1)],vv+=v[k+(n>>1)];
            ll t=m-ww;
            //cout<<ww<<' '<<vv<<endl; 
            if(t<0)continue;
            //printf("found(%d) for %d
    ",binary_search(t),t);
            ans=max(ans,max_val[binary_search(t)]+vv);    
        } 
        cout<<ans;
        return 0;
    }
    
    /*
    dialog
    折半搜索
    T(n)=O(2^(n/2)*n)
    *极限数据还挺快的。。就不优化了 
    
    */

    T3

    image

    n,m<=5000

    区间dp+四边形不等式

    对于每个节点代表的区间[l,r],求出这个子树中最少访问次数,一个节点被访问一次当且仅当查询区间和他相交

    然后这个东西是一个四边形不等式的形式

    #include<stdio.h>
    #include<iostream>
    #include<stdlib.h>
    #include<math.h>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #define il inline
    #define re register
    #define lowbit(x) (x&(-x))
    using namespace std;
    typedef long long ll;
    int n,m,a[100010],b[100010],s[5010],g[5010][5010],end[5010],begin[5010],c[5010][5010];
    ll f[5010][5010];
    il void init(){
        for(int l=2;l<=n;l++){
            for(int i=1,j;i<=n-l+1;i++){
                j=i+l-1;f[i][j]=(1ll<<50);
                for(int k=i;k<j;k++){
                    if(f[i][j]>f[i][k]+f[k+1][j]+g[i][j]){
                        c[i][j]=k;f[i][j]=f[i][k]+f[k+1][j]+g[i][j];
                    }
                }    
            }
        }
        cout<<f[1][n];
    }
    int main(){
        freopen("segment.in","r",stdin);
        freopen("segment.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a[i],&b[i]);
            end[b[i]]++;begin[a[i]]++;
        }
        for(int i=1;i<=n;i++) end[i]+=end[i-1];
        for(int i=n;i>=1;i--) begin[i]+=begin[i+1];
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++)
                g[i][j]=m-end[i-1]-begin[j+1];
        for(int i=1;i<=n;i++) f[i][i]=g[i][i];
        if(n<=200){
            init();return 0;
        }
        for(int i=1;i<=n;i++) c[i][i]=i;
        for(int l=2;l<=n;l++){
            for(int i=1,j;i<=n-l+1;i++){
                j=i+l-1;f[i][j]=(1ll<<50);
                for(int k=max(i,c[i][j-1]);k<j&&k<=c[i+1][j];k++){
                    if(f[i][j]>f[i][k]+f[k+1][j]+g[i][j]){
                        c[i][j]=k;f[i][j]=f[i][k]+f[k+1][j]+g[i][j];
                    }
                }    
            }
        }
        cout<<f[1][n];
        return 0;
    }
  • 相关阅读:
    .NET Core 中依赖注入 AutoMapper 小记
    40款用于简洁网页设计的光滑英文字体【上】
    AOS – 另外一个独特的页面滚动动画库(CSS3)
    分享20个新颖的字体设计草图,带给你灵感
    Cleave.js – 自动格式化表单输入框的文本内容
    CssStats – 分析和优化网站 CSS 代码的利器
    20款 JavaScript 开发框架推荐给前端开发者
    12个用于网站性能优化的最佳的图片压缩工具
    16款最佳的 jQuery Time Picker 时间选择插件
    2016年6月份那些最实用的 jQuery 插件专辑
  • 原文地址:https://www.cnblogs.com/chouti/p/5788969.html
Copyright © 2020-2023  润新知