zoukankan      html  css  js  c++  java
  • [atARC063F]Snuke's Coloring 2

    首先,可以通过将所有$x_{i}=0$都选择第1类,其余选第2类,构造出一个以$(0,0)$和$(1,h)$为左下角和右上角的矩形,答案即为$2h+2$,类似地还可以构造出$2w+2$

    若最终的矩形不包含与$x=frac{w}{2}$或$y=frac{h}{2}$,那么意味着答案不超过$w+h$,而上面的构造得到了答案$2max(w,h)+2$的下限,因此一定不优

    接下来,我们分别考虑与$x=frac{w}{2}$有交和与$y=frac{h}{2}$有交的答案,取max即可

    以$y=frac{h}{2}$为例,暴力枚举右端点的$x$(记作$x_{i}$),即找到$j$,并最大化$x_{i}-x_{j}+Delta y_{j+1,i-1}$(其中$Delta y_{i,j}$指对应的最小的$y$坐标差,即$min_{ile kle j,y_{k}>frac{h}{2}}y_{k}-max_{ile kle j,y_{k}le frac{h}{2}}y_{k}$)

    (关于$Delta y_{i,j}$中若存在$ile kle j$且$y_{k}=frac{h}{2}$,看上去会有两种可能,但一定不优,任取即可)

    $x_{i}$是关于$i$的常数,即要求最大化$Delta y_{j+1,i-1}-x_{j}$,注意到每一次增加$i$也就是对$Delta y_{j+1,i-1}$执行区间修改,修改的区间个数恰好与单调栈弹出数相同,用线段树来维护$Delta y_{j+1,i-1}-x_{j}$最大值即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 300005
     4 #define oo 0x3f3f3f3f
     5 #define L (k<<1)
     6 #define R (L+1)
     7 #define mid (l+r>>1)
     8 #define fi first
     9 #define se second
    10 stack<int>st[2];
    11 pair<int,int>a[N];
    12 int n,w,h,ans,f[N<<2],tag[N<<2];
    13 void upd(int k,int x){
    14     tag[k]+=x;
    15     f[k]+=x;
    16 }
    17 void down(int k){
    18     upd(L,tag[k]);
    19     upd(R,tag[k]);
    20     tag[k]=0;
    21 }
    22 void update(int k,int l,int r,int x,int y,int z){
    23     if ((l>y)||(x>r))return;
    24     if ((x<=l)&&(r<=y)){
    25         upd(k,z);
    26         return;
    27     }
    28     down(k);
    29     update(L,l,mid,x,y,z);
    30     update(R,mid+1,r,x,y,z);
    31     f[k]=max(f[L],f[R]); 
    32 }
    33 void calc(){
    34     sort(a+1,a+n+1);
    35     while (!st[0].empty())st[0].pop();
    36     st[0].push(0);
    37     while (!st[1].empty())st[1].pop();
    38     st[1].push(0);
    39     memset(tag,0,sizeof(tag));
    40     memset(f,0,sizeof(f));
    41     upd(1,-oo);
    42     int hh=h/2;
    43     for(int i=1;i<=n;i++){
    44         update(1,1,n,i,i,oo+h-a[i-1].fi);
    45         ans=max(ans,a[i].fi+f[1]);
    46         int p=(a[i].se>hh),las=i,x=abs(a[i].se-hh)-abs(p*h-hh);
    47         while (1){
    48             update(1,1,n,st[p].top()+1,las,x);
    49             las=st[p].top();
    50             x=abs(a[i].se-hh)-abs(a[las].se-hh);
    51             if ((!las)||(x>0))break;
    52             st[p].pop();
    53         }
    54         st[p].push(i);
    55     }
    56     ans=max(ans,w+max(f[1],h-a[n].fi));
    57 }
    58 int main(){
    59     scanf("%d%d%d",&w,&h,&n);
    60     for(int i=1;i<=n;i++)scanf("%d%d",&a[i].fi,&a[i].se);
    61     calc();
    62     swap(w,h);
    63     for(int i=1;i<=n;i++)swap(a[i].fi,a[i].se);
    64     calc();
    65     printf("%d",2*ans);
    66 }
    View Code
  • 相关阅读:
    hbase单机安装和简单使用
    工作随记--div最小高度
    工作随记——弹出QQ联系方式
    关于vs2012解决方案中项目DLL文件引用问题
    工作随想——框架之我见
    jQuery 选择表格(table)里的行和列及改变简单样式
    ASP.NET的Get和Post方式的区别归纳总结
    C# 静态类与非静态类、静态成员的区别
    引用静态资源的url添加版本号,解决版本发布后的浏览器缓存有关问题
    python技巧 一等函数
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14464109.html
Copyright © 2011-2022 走看看