• bzoj3463【COCI2012】 Inspector


    题目描述

    在一个小国家中,一个新的小镇终于建成了!如往常一样,Mirko获得了“首席税务巡查员”的职位。他的任务是保证正确地计算各公司的收入情况。一共有N家办公室坐落在主干道上,从左到右被编号为1~N。一开始,所有办公室一开始都是空的。随后,一些公司会搬入或搬出某些办公室。Mirko时不时地会经过某些办公室并审查在这些办公室中,最富有的公司的账目。

    一个公司被以如下的方式描述:

    T-表示搬入的第一天。

    K-表示搬入的办公室的标号。

    Z-公司每日的盈利。(可以是负值表示亏损)

    S-公司搬入时的公司财务情况。(即公司的账户资金,也可以是负值)

    如果一家公司已经在 K 办公室了,当有新公司要进入 K 办公室时,这家公司会立刻搬出。

    新公司第一天并不会运营,盈利从第二天开始计算。

    Mirko的审查以 3 个整数来描述:

    T-审查的时间。

    A 和 B-Mirko会检查 A 办公室至 B 办公室(包括A和B)之间的公司。

    Mirko只会在一天结束时检查,所有公司这时已经计算完成了当天利润。


    输入格式

    第一行包含 2 个正整数:N(1<=N<=100000)表示办公室的数量和M(1<=M<=300000)表示事件的个数。

    接下来 M 行,遵循以下格式:“1 T K Z S”或“2 T A B”(含义如题目描述)。其中 T 会严格递增,并且最后一天小于 1000000,Z 和 S 的绝对值也严格小于 1000000。

    (注意A可能大于B)


    输出格式

    对于每次Mirko的审查,每行输出一个整数,表示当天最富有的公司的资产(可以为负)。如果Mirko经过的所有办公室中都没有公司入驻,则输出“nema”(不加引号)。


    • 题解:

      • 由于$T$单调递增,所以题意是支持插入,求某个点在标号为$[L,R]$的一次函数上的最大值;
      • 答案一定在下凸壳上,分块维护凸壳,有修改操作就打修改标记,查询时遇到修改标记暴力重构区间的凸壳;
      • 同时$T$是单调递增的,可以维护每个块的最优值位置,查询向后移动;
      • 设分块大小为$B$
      • $T = nB log B+frac{n^2}{B}     = n( BlogB + frac{n}{B})$
      • 取$B = sqrt{frac{n}{logn}}$,$T = O(n sqrt{n} sqrt{log n})$
      •  1 #include<cstdio>
         2 #include<iostream>
         3 #include<algorithm>
         4 #include<cstring>
         5 #include<queue>
         6 #include<cmath>
         7 #include<vector>
         8 #include<stack>
         9 #include<map>
        10 #include<set>
        11 #define Run(i,l,r) for(int i=l;i<=r;i++)
        12 #define Don(i,l,r) for(int i=l;i>=r;i--)
        13 #define ll long long
        14 #define ld double
        15 #define mk make_pair
        16 #define fir first
        17 #define sec second
        18 #define il inline
        19 #define rg register
        20 #define pb push_back
        21 using namespace std;
        22 const int N=100010;
        23 const ll inf = 1e18;
        24 int n,m,u,bl[N],st[N],ed[N],vis[N],mfy[N],L[N],R[N],used[N];
        25 ld px[N];
        26 il char gc(){
        27     static char*p1,*p2,s[1000000];
        28     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
        29     return(p1==p2)?EOF:*p1++;
        30 } 
        31 il int rd(){
        32     int x=0,f=1; char c=gc();
        33     while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
        34     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
        35     return x*f;
        36 }
        37 struct line{
        38     ll k,b;
        39     line(ll _k=0,ll _b=0):k(_k),b(_b){}; 
        40     bool operator <(const line&l)const{return k==l.k?b>l.b:k<l.k;}
        41 }a[N],b[N];
        42 ld calx(line x,line y){return (ld)(x.b-y.b)/(y.k-x.k);}
        43 il void build(int x){
        44     int cnt=st[x],top=st[x];
        45     for(rg int i=st[x];i<=ed[x];++i)if(vis[i])b[cnt++]=a[i];
        46     sort(b+st[x],b+cnt);
        47     for(rg int i=st[x]+1;i<cnt;++i)if(b[i].k!=b[i-1].k){
        48         while(top>st[x]&&calx(b[i],b[top])<px[top-1])top--;
        49         px[top]=calx(b[i],b[top]);b[++top]=b[i];
        50     }
        51     L[x]=st[x];R[x]=top;
        52 }
        53 il ll max(ll x,ll y){return x>y?x:y;}
        54 il void query(int T,int x,int y){
        55     if(x>y)swap(x,y);
        56     ll re=-inf;
        57     int l=bl[x],r=bl[y];
        58     if(l==r){for(rg int i=x;i<=y;++i)if(vis[i])re=max(re,a[i].k*T+a[i].b);}
        59     else{
        60         for(rg int i=x;i<=ed[bl[x]];++i)if(vis[i])re=max(re,a[i].k*T+a[i].b);
        61         for(rg int i=st[bl[y]];i<=y;++i)if(vis[i])re=max(re,a[i].k*T+a[i].b);
        62         for(rg int i=l+1;i<r;++i){
        63             if(mfy[i])build(i),mfy[i]=0,used[i]=1;
        64             if(used[i]){
        65                 while(L[i]<R[i]&&px[L[i]]<T)L[i]++;
        66                 re=max(re,b[L[i]].k*T+b[L[i]].b);
        67             }
        68         }
        69     }
        70     if(re==-inf)puts("nema");else printf("%lld
        ",re);
        71 }
        72 int main(){
        73     #ifndef ONLINE_JUDGE
        74     freopen("bzoj3463.in","r",stdin);
        75     freopen("bzoj3463.out","w",stdout);
        76     #endif
        77     n=rd();m=rd();u=sqrt(n/log2(n))+1;
        78     for(int i=1;i<=n;++i)bl[i]=(i-1)/u+1;
        79     for(int i=1;i<=bl[n];++i)st[i]=ed[i-1]+1,ed[i]=ed[i-1]+u;
        80     ed[bl[n]]=n;
        81     for(int i=1,op,T,x,y;i<=m;++i){
        82         op=rd();T=rd();x=rd();y=rd();
        83         if(op&1){
        84             vis[x]=1;mfy[bl[x]]=1;
        85             a[x]=line(y,rd()-(ll)T*y); 
        86         }else query(T,x,y);
        87     }
        88     return 0;
        89 }//by tkys_Austin;
        bzoj3463
  • 相关阅读:
    BZOJ1264 [AHOI2006]基因匹配Match 动态规划 树状数组
    BZOJ1845 [Cqoi2005] 三角形面积并 扫描线 计算几何
    BZOJ1258 [CQOI2007]三角形tri 模拟
    BZOJ4972 八月月赛 Problem B 小Q的方格纸 二维前缀和
    BZOJ1218 [HNOI2003]激光炸弹 二维前缀和
    BZOJ1263 [SCOI2006]整数划分 高精度
    BZOJ1209 [HNOI2004]最佳包裹 三维凸包 计算几何
    BZOJ1207 [HNOI2004]打鼹鼠 动态规划
    BZOJ1202 [HNOI2005]狡猾的商人 spfa
    BZOJ1201 [HNOI2005]数三角形 大力出奇迹
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10269990.html
Copyright © 2020-2023  润新知