P3474 [POI2008]KUP-Plot purchase

Posted jackpei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3474 [POI2008]KUP-Plot purchase相关的知识,希望对你有一定的参考价值。

思路:单调栈

提交:>5次

错因:单调栈写法有问题+前缀和写错

题解:

若有\(>=k\ \&\&\ <=2\times k\)的点,显然直接选他就行了。
否则,我们需要找到一个矩形(不一定只有一个),并且这个矩形只包含\(<k\)的点且总权值和\(>=2k\)
这样,我们可以尝试去切掉他的行来不断减少他的权值和。
如果发现某一行 \(>=2k\) ,我们应该去且他而不是切剩下的矩形(剩下的可能过小)。
当然如果你切着切着发现出现了一个矩形他的权值和\(>=k\ \&\&\ <=2\times k\) ,直接输出就好。

#include<bits/stdc++.h>
#define ll long long
#define R register int
using namespace std;
namespace Luitaryi 
template<class I> inline I g(I& x)  x=0; register I f=1;
  register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
  do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
 const int N=2010; 
int n,k,k2,x1,x2,y1,y2;
int up[N][N],l[N],r[N],stk[N],top;
ll a[N][N],s[N][N],mx;
inline void change(int up,int dn,int l,int r) 
  R sum=s[dn][r]-s[up-1][r]-s[dn][l-1]+s[up-1][l-1];
  if(sum>=k&&sum<=k2) 
    printf("%d %d %d %d\n",l,up,r,dn); exit(0); 
  
  if(sum>mx) mx=sum,x1=up,x2=dn,y1=l,y2=r;

inline void solve() 
  for(R i=x2;i>=x1;--i) 
    register ll sum=s[i][y2]-s[i-1][y2]-s[i][y1-1]+s[i-1][y1-1];
    if(sum>=k&&sum<=k2) return (void) printf("%d %d %d %d\n",y1,i,y2,i);
    if(sum>k2) 
      for(R p=y2;p>=y1;--p) 
        sum-=a[i][p]; 
        if(sum>=k&&sum<=k2) return (void) printf("%d %d %d %d\n",y1,i,p-1,i);
      
     mx-=sum; 
    if(mx>=k&&mx<=k2) return (void) printf("%d %d %d %d\n",y1,i+1,y2,x2);
  

inline void main()  freopen("in.in","r",stdin);
  g(k),k2=k<<1,g(n); for(R i=1;i<=n;++i) for(R j=1;j<=n;++j) 
    s[i][j]=g(a[i][j])+s[i][j-1]; if(a[i][j]>=k&&a[i][j]<=k2) 
      return (void)printf("%d %d %d %d\n",i,j,i,j);
   for(R i=1;i<=n;++i) for(R j=1;j<=n;++j) s[i][j]+=s[i-1][j];
  for(R i=1;i<=n;++i) 
    for(R j=1;j<=n;++j) if(a[i][j]<k) up[i][j]=up[i-1][j]+1;
    stk[top=1]=0,up[i][0]=-1; for(R j=1;j<=n;++j) 
      while(top&&up[i][stk[top]]>=up[i][j]) --top;
      l[j]=stk[top]+1,stk[++top]=j;
     stk[top=1]=n+1,up[i][n+1]=-1; 
    for(R j=n;j;--j) 
      while(top&&up[i][stk[top]]>=up[i][j]) --top;
      r[j]=stk[top]-1,stk[++top]=j;
      if(up[i][j]) change(i-up[i][j]+1,i,l[j],r[j]);
     
   
  if(mx<k) return (void) puts("NIE"); solve();

 signed main() Luitaryi::main(); return 0;

2019.09.03
66

以上是关于P3474 [POI2008]KUP-Plot purchase的主要内容,如果未能解决你的问题,请参考以下文章

3469 [POI2008]BLO-Blockade

BZOJ1129: [POI2008]Per

BZOJ1131 [POI2008]Sta 其他

AC日记——[POI2008]BLO-Blockade 洛谷 [POI2008]BLO-Blockade

[POI2008]BLO

1123: [POI2008]BLO