• BZOJ3463 : [COCI2012] Inspector


    考虑将序列分成$sqrt{nlog n}$块,每块维护下凸壳,修改时在相应块打上需要修改的标记。

    查询时,对于两端零散部分暴力查询。

    对于中间的块,如果有修改标记,则暴力重构。

    然后在凸壳上查询时不断把小于$T$的左端点踢出,那么最后如果凸壳上还有点,那么左端点一定$geq T$。

    时间复杂度$O(msqrt{nlog n})$。

    #include<cstdio>
    #include<algorithm>
    #define N 100010
    using namespace std;
    typedef long long ll;
    const ll inf=1LL<<60;
    int n,m,lim,i,op,T,x,y,z,id[N],st[N],en[N],L[N],R[N],need[N],b[N],q[N];ll ans;
    struct P{int k;ll b;P(){}P(int _k,ll _b){k=_k,b=_b;}}a[N];
    inline bool cmp(int x,int y){return a[x].k==a[y].k?a[x].b>a[y].b:a[x].k<a[y].k;}
    inline void read(int&a){
      char c;bool f=0;a=0;
      while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
      if(c!='-')a=c-'0';else f=1;
      while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
      if(f)a=-a;
    }
    inline double pos(int x,int y){return 1.0*(a[x].b-a[y].b)/(a[y].k-a[x].k);}
    inline void build(int x){
      int cnt=0,t=st[x],i;
      for(i=t;i<=en[x];i++)if(a[i].b>-inf||i==t)q[++cnt]=i;
      sort(q+1,q+cnt+1,cmp);
      for(b[t]=q[1],i=2;i<=cnt;i++)if(a[q[i]].k!=a[q[i-1]].k){
        while(t>st[x]&&pos(q[i],b[t])<pos(b[t],b[t-1]))t--;
        b[++t]=q[i];
      }
      L[x]=st[x],R[x]=t;
    }
    inline void ask(int x){
      while(L[x]<R[x]&&(double)T>pos(b[L[x]],b[L[x]+1]))L[x]++;
      if(L[x]<=R[x])ans=max(ans,1LL*a[b[L[x]]].k*T+a[b[L[x]]].b);
    }
    inline void getans(int x,int y){
      if(id[x]==id[y]){
        for(;x<=y;x++)ans=max(ans,1LL*a[x].k*T+a[x].b);
        return;
      }
      for(i=en[id[x]];i>=x;i--)ans=max(ans,1LL*a[i].k*T+a[i].b);
      for(i=st[id[y]];i<=y;i++)ans=max(ans,1LL*a[i].k*T+a[i].b);
      for(i=id[x]+1;i<id[y];i++){
        if(need[i])build(i),need[i]=0;
        ask(i);
      }
    }
    int main(){
      read(n),read(m);
      for(i=1;1<<i<n;i++);
      while(lim*lim*i<n)lim++;
      for(i=1;i<=n;i++)en[id[i]=i/lim]=i;
      for(i=n;i;i--)st[id[i]]=i;
      for(i=1;i<=n;i++)a[i]=P(0,-inf);
      for(i=id[1];i<=id[n];i++)L[i]=1;
      while(m--){
        read(op),read(T),read(x),read(y);
        if(op==1){
          read(z);
          a[x]=P(y,-1LL*y*T+z);
          need[id[x]]=1;
        }else{
          if(x>y)swap(x,y);
          ans=-inf;
          getans(x,y);
          if(ans>-inf)printf("%lld
    ",ans);else puts("nema");
        }
      }
      return 0;
    }
    

      

  • 相关阅读:
    tar打包如何不打包某一个文件夹(排除某些文件夹)
    第一个SpringBoot应用
    Linux(以RHEL7为例)下添加工作区的方法|| The Way To Add Workspace On Linux
    Linux(以centos7为例)下自动挂载NTFS硬盘
    基于Moodle的IT课程辅助教育平台搭建
    搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台
    如何利用word2013写图文并茂的博客
    如何安装win10+Red Hat Enterprise Linux双系统?
    课堂练习:ex 4-20
    实验二 函数重载、函数模板、简单类的定义和实现
  • 原文地址:https://www.cnblogs.com/clrs97/p/4862780.html
Copyright © 2020-2023  润新知