zoukankan      html  css  js  c++  java
  • BZOJ3521: [Poi2014]Salad Bar

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3521

    题解:我们考虑把p当作1,j当作-1,然后a[i]表示前缀和。

              画到网格图上,我们很容易观察出,[l,r]满足题中的条件当且仅当 a[l-1]是a[l...r]的最小值,而a[r]是a[l...r]的最大值。

              那这样就很简单了,我们先用单调栈求出l[i],r[i],分别表示 a[i]作为最大值最远拓展到l[i],作为最小值最远拓展到r[i]。

              然后我们可以枚举区间的左端点,查询i-r[i]之间l[x]<=i的。这一步我们可以串个链表,r[x]<=i的时候就把它添入答案候选,然后查询区间最值。

              线段树即可。

    代码:

      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 1000000+5
     26 
     27 #define maxm 200000+5
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
     44 
     45 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
     46 
     47 #define mod 1000000007
     48 #define mid ((l+r)>>1)
     49 #define lch k<<1,l,mid
     50 #define rch k<<1|1,mid+1,r
     51 
     52 using namespace std;
     53 
     54 inline int read()
     55 
     56 {
     57 
     58     int x=0,f=1;char ch=getchar();
     59 
     60     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     61 
     62     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     63 
     64     return x*f;
     65 
     66 }
     67 int n,tot,head[maxn],a[maxn],l[maxn],r[maxn],sta[maxn];
     68 struct seg{int mx;}t[4*maxn];
     69 struct edge{int go,next;}e[maxn];
     70 inline void add(int x,int y)
     71 {
     72     e[++tot]=(edge){y,head[x]};head[x]=tot;
     73 }
     74 inline void pushup(int k)
     75 {
     76     t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
     77 }
     78 inline void change(int k,int l,int r,int x)
     79 {
     80     if(l==r){t[k].mx=l;return;}
     81     if(x<=mid)change(lch,x);else change(rch,x);
     82     pushup(k);
     83 }
     84 inline int query(int k,int l,int r,int x,int y)
     85 {
     86     if(l==x&&r==y)return t[k].mx;
     87     if(y<=mid)return query(lch,x,y);
     88     else if(x>mid)return query(rch,x,y);
     89     else return max(query(lch,x,mid),query(rch,mid+1,y));
     90 }
     91 
     92 int main()
     93 
     94 {
     95 
     96     freopen("input.txt","r",stdin);
     97 
     98     freopen("output.txt","w",stdout);
     99 
    100     n=read()+1;
    101     for2(i,2,n)
    102     {
    103         char ch=getchar();
    104         while(ch!='p'&&ch!='j')ch=getchar();
    105         a[i]=a[i-1]+(ch=='p'?1:-1);
    106     }
    107     int top=0;
    108     a[n+1]=-inf;
    109     for1(i,n+1)
    110     {
    111         while(top&&a[sta[top]]>a[i])r[sta[top--]]=i-1;
    112         sta[++top]=i;
    113     }
    114     top=0;a[0]=inf;
    115     for3(i,n,0)
    116     {
    117         while(top&&a[sta[top]]<a[i])l[sta[top--]]=i+1;
    118         sta[++top]=i;
    119     }
    120     for1(i,n)add(l[i],i);
    121     int ans=0;
    122     for1(x,n)
    123     {
    124         for4(i,x)change(1,1,n,y);
    125         ans=max(ans,query(1,1,n,x,r[x])-x);
    126         //cout<<x<<' '<<a[x]<<' '<<l[x]<<' '<<r[x]<<' '<<query(1,1,n,x,r[x])-x<<endl;
    127     }
    128     cout<<ans<<endl;
    129 
    130     return 0;
    131 
    132 }  
    View Code

             

  • 相关阅读:
    关于lockkeyword
    关于多层for循环迭代的效率优化问题
    Android 面试精华题目总结
    Linux基础回想(1)——Linux系统概述
    linux源代码编译安装OpenCV
    校赛热身 Problem C. Sometimes Naive (状压dp)
    校赛热身 Problem C. Sometimes Naive (状压dp)
    校赛热身 Problem B. Matrix Fast Power
    校赛热身 Problem B. Matrix Fast Power
    集合的划分(递推)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4257754.html
Copyright © 2011-2022 走看看