zoukankan      html  css  js  c++  java
  • P3474 [POI2008]KUP-Plot purchase

    思路:单调栈

    提交:>5次

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

    题解:

    若有(>=k && <=2 imes k)的点,显然直接选他就行了。
    否则,我们需要找到一个矩形(不一定只有一个),并且这个矩形只包含(<k)的点且总权值和(>=2k)
    这样,我们可以尝试去切掉他的行来不断减少他的权值和。
    如果发现某一行 (>=2k) ,我们应该去且他而不是切剩下的矩形(剩下的可能过小)。
    当然如果你切着切着发现出现了一个矩形他的权值和(>=k && <=2 imes 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
    ",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
    ",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
    ",y1,i,p-1,i);
          }
        } mx-=sum; 
        if(mx>=k&&mx<=k2) return (void) printf("%d %d %d %d
    ",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
    ",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

  • 相关阅读:
    数据库表的主外键
    数据库条件查询及关系搭建
    MySQL数据库的基本认识与操作
    MySQL5.7安装详解及常见安装问题解决
    数据库介绍
    Sensor图像调试
    1.线性表
    发展建议
    typedef 与 #define 的区别
    音频处理
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11455396.html
Copyright © 2011-2022 走看看