zoukankan      html  css  js  c++  java
  • BZOJ2388: 旅行规划

    n<=1e5个数,m<=1e5个操作:区间加,查区间最大的1~i号点的和。

    第一次见到nsqrt(n)logn能过1e5的。。然而跑得很慢

    普通数据结构感觉难下手,那就分块。先处理前缀和数组。一次修改,实际上把一段前缀和加上了一个等差数列,然后把这区间后面的前缀和加上某个固定数字,也可以看成另一个等差数列。等差数列叠加依然是等差数列,那就考虑整块打上一个A,B标记表示这一块加上首项(A+B)公差B的等差数列后的结果。

    假设一块里的第i个数是Si,那如果i比j优(j>i),就有

    $s_i+i*B+A>s_j+j*B+A$

    整理得

    $frac{s_i-s_j}{j-i}>B$

    嘿嘿,每个块维护个凸包就搞定了

    实测块大小取150跑得比较快。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<algorithm>
      5 #include<math.h>
      6 //#include<time.h>
      7 //#include<iostream>
      8 using namespace std;
      9 
     10 int n,m,q;
     11 #define maxn 100011
     12 #define maxm 561
     13 #define LL long long
     14 int bel[maxn],tot; LL shou[maxm],cha[maxm],a[maxn],tu[maxm][maxm];
     15 double calc(int i,int j) {return 1.0*(a[i]-a[j])/(j-i);}
     16 void maketu(int x)
     17 {
     18     int l=(x-1)*m+1,r=min(x*m,n);
     19     tu[x][0]=0;
     20     for (int i=l;i<=r;i++)
     21     {
     22         while (tu[x][0]>1 && calc(tu[x][tu[x][0]-1],tu[x][tu[x][0]])>=calc(tu[x][tu[x][0]],i)) tu[x][0]--;
     23         tu[x][++tu[x][0]]=i;
     24     }
     25 }
     26 void down(int x)
     27 {
     28     if (!shou[x] && !cha[x]) return;
     29     int l=(x-1)*m+1,r=min(x*m,n);
     30     for (int i=l,cnt=1;i<=r;i++,cnt++) a[i]+=shou[x]+cha[x]*cnt;
     31     shou[x]=cha[x]=0;
     32 }
     33 void modifysingle(int x,int y,LL s,LL v)
     34 {
     35     if (x>y) return;
     36     down(bel[x]);
     37     for (int i=x,cnt=1;i<=y;i++,cnt++) a[i]+=s+cnt*v;
     38     maketu(bel[x]);
     39 }
     40 void modify(int x,int y,LL v)
     41 {
     42     if (bel[x]==bel[y]) 
     43     {
     44         modifysingle(x,y,0,v);
     45         LL s1=(y-x+1)*v;
     46         modifysingle(y+1,min(bel[y]*m,n),(y-x+1)*v,0);
     47         for (int i=bel[y]+1;i<=tot;i++) shou[i]+=s1;
     48     }
     49     else
     50     {
     51         LL s1=(bel[x]*m-x+1)*v,s2=((bel[y]-1)*m-x+1)*v,s3=(y-x+1)*v;
     52         for (int i=bel[x]+1;i<bel[y];i++) shou[i]+=s1,cha[i]+=v,s1+=m*v;
     53         modifysingle(x,bel[x]*m,0,v);
     54         modifysingle((bel[y]-1)*m+1,y,s2,v);
     55         modifysingle(y+1,min(bel[y]*m,n),s3,0);
     56         for (int i=bel[y]+1;i<=tot;i++) shou[i]+=s3;
     57     }
     58 }
     59 LL querysingle(int x,int y)
     60 {
     61     down(bel[x]);
     62     LL ans=-1e18;
     63     for (int i=x;i<=y;i++) ans=max(ans,a[i]);
     64     maketu(bel[x]);
     65     return ans;
     66 }
     67 LL query(int x,int y)
     68 {
     69     if (bel[x]==bel[y]) return querysingle(x,y);
     70     else
     71     {
     72         LL ans=-1e18;
     73         for (int i=bel[x]+1;i<bel[y];i++)
     74         {
     75             int L=1,R=tu[i][0];
     76             while (L<R)
     77             {
     78                 const int mid=(L+R)>>1;
     79                 if (calc(tu[i][mid],tu[i][mid+1])>=cha[i]) R=mid;
     80                 else L=mid+1;
     81             }
     82             ans=max(ans,a[tu[i][L]]+shou[i]+(tu[i][L]-(i-1)*m)*cha[i]);
     83         }
     84         ans=max(ans,querysingle(x,bel[x]*m));
     85         ans=max(ans,querysingle((bel[y]-1)*m+1,y));
     86         return ans;
     87     }
     88 }
     89 int main()
     90 {
     91     scanf("%d",&n);
     92     m=min(150,n);
     93     for (int i=1;i<=n;i++) bel[i]=(i-1)/m+1;
     94     tot=bel[n];
     95     
     96     for (int i=1;i<=n;i++) scanf("%lld",&a[i]),a[i]+=a[i-1];
     97     for (int i=1;i<=tot;i++) maketu(i);
     98     
     99     scanf("%d",&q);
    100     int id,x,y,z;
    101     while (q--)
    102     {
    103         scanf("%d",&id);
    104         if (id)
    105         {
    106             scanf("%d%d",&x,&y);
    107             printf("%lld
    ",query(x,y));
    108         }
    109         else
    110         {
    111             scanf("%d%d%d",&x,&y,&z);
    112             modify(x,y,z);
    113         }
    114     }
    115     return 0;
    116 }
    View Code
  • 相关阅读:
    UVA1349 Optimal Bus Route Design 最优巴士路线设计
    POJ3565 Ants 蚂蚁(NEERC 2008)
    UVA1663 Purifying Machine 净化器
    UVa11996 Jewel Magic 魔法珠宝
    NEERC2003 Jurassic Remains 侏罗纪
    UVA11895 Honorary Tickets
    gdb调试coredump(使用篇)
    使用 MegaCLI 检测磁盘状态并更换磁盘
    员工直接坦诚直来直去 真性情
    山东浪潮超越3B4000申泰RM5120-L
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8042631.html
Copyright © 2011-2022 走看看