zoukankan      html  css  js  c++  java
  • UOJ#29. 【IOI2014】Holiday

    传送门

    分析

    真不明白这道题为啥要是交互题,难道是为了普及交互题这种题型???嘤嘤嘤

    见到这个题的第一个反应:网络流?建一个流量是d的边??

    第二个反映:如果对于起点为0的情况可以dp,所以只要把左半段接到右半段后面或者右半段接到左半段后面然后通过一些奇怪的东西转移即可,复杂度O(nd)??

    第三个反映:我在扯淡!

    正解:

    我们知道路线一定是先向一边走一段再折返回来走另一边(也可能不回来了)

    于是对于一段路径[le,ri]我们可以先把一共要走多远计算出来,剩下k天就是在主席树中寻找这一段前k大数的和

    然后我们又得到一个非常明显的性质:

      我们设f(x)为向一个方向不回头走x天的最大值,g(x)为回头的最大值

      则对于任意i<j都有f(i)<=f(j),g(i)<=g(j)

    这玩意有个学名叫决策单调性

    于是我们可以考虑二分右边的点mid,然后对于二分到的点枚举左边的点求出它的最大值

    设此时它对应的左边的点为pl则当右边点小于mid时左边对应的点一定不大于pl,右边点大于mid时反之

    代码

    #include"holiday.h"
    #include<bits/stdc++.h>
    using namespace std;
    #define li long long
    int a[100100],v[100100],s,D,n,m,root[100100],cnt;
    li Ans;
    struct node {
        int le,ri,sum;
        li ans;
    };
    node d[4400000];
    inline void update(int le,int ri,int &x,int y,int k){
        d[++cnt]=d[y];
        x=cnt;
        d[x].sum++;
        d[x].ans+=v[k];
        if(le==ri)return;
        int mid=(le+ri)>>1;
        if(k<=mid)update(le,mid,d[x].le,d[y].le,k);
          else update(mid+1,ri,d[x].ri,d[y].ri,k);
    }
    inline li q(int le,int ri,int x,int y,int k){
        if(le==ri)return (li)v[le]*min(k,d[y].sum-d[x].sum);
        int mid=(le+ri)>>1,tot=d[d[y].ri].sum-d[d[x].ri].sum;
        if(tot>=k)return q(mid+1,ri,d[x].ri,d[y].ri,k);
          else return d[d[y].ri].ans-d[d[x].ri].ans+q(le,mid,d[x].le,d[y].le,k-tot);
    }
    inline void solve(int L,int R,int le,int ri){
        li res=0,tot=0;
        int i,j,k,pl=R,mid=(le+ri)>>1;
        for(i=L;i<=R;i++){
          k=D-(mid-i)-min(mid-s,s-i);
          if(k){
              tot=q(1,m,root[i-1],root[mid],k);
              if(tot>res){
                res=tot;
                pl=i;
              }
          }
        }
        Ans=max(Ans,res);
        if(mid>le)solve(L,pl,le,mid-1);
        if(mid<ri)solve(pl,R,mid+1,ri);
    }
    li findMaxAttraction(int nn, int ss, int dd, int aa[]){
        int i,j,k;
        n=nn,s=ss,D=dd;
        s++;
        for(i=1;i<=n;i++)a[i]=aa[i-1],v[i]=aa[i-1];
        sort(v+1,v+n+1);
        m=unique(v+1,v+n+1)-v-1;
        for(i=1;i<=n;i++)
          update(1,m,root[i],root[i-1],lower_bound(v+1,v+m+1,a[i])-v);
        solve(1,s,s,n);
        return Ans;
    }
  • 相关阅读:
    pytorch lstm crf 代码理解
    python sys.argv是什么?
    如何用简单易懂的例子解释条件随机场(CRF)模型?它和HMM有什么区别?
    jieba分词工具的使用方法
    手把手教你用Python实现自动特征工程
    命名实体识别视频51cto
    命名实体识别入门教程(必看)
    零基础入门--中文命名实体识别(BiLSTM+CRF模型,含代码)
    自然语言处理深度学习篇-BiLSTM文本挖掘实践 命名实体识别
    导航栏颜色
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10368717.html
Copyright © 2011-2022 走看看