zoukankan      html  css  js  c++  java
  • 联考20200730 T3 小B的农场


    分析:
    没挖掘出性质可以\(O(n^2logn)\)得到60分。。。
    发现\(1*n\)的农田是一定划得出来的,所以答案最小为\(2(max(W,H)+1)\)
    之后我们发现如果要比这个答案大,农田一定过横向或者纵向的中线
    假设过纵向中线(横向的同样处理)
    每一次下边界向下拓展时,新加入的会对左右限制的点用线段维护一下就好了
    复杂度\(O(nlogn)\)

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    
    #define maxn 300005
    #define INF 0x3f3f3f3f
    #define MOD 998244353
    
    using namespace std;
    
    inline long long getint()
    {
    	long long num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,W,H,ans;
    struct node{
    	int x,y;
    }p[maxn];
    int mx[maxn<<2],lz[maxn<<2];
    int s1[maxn],t1,s2[maxn],t2;
    
    inline void build(int i,int l,int r)
    {
    	lz[i]=0,mx[i]=-p[l].y;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	build(i<<1,l,mid),build(i<<1|1,mid+1,r);
    }
    
    inline void update(int i,int l,int r,int ql,int qr,int x)
    {
    	if(qr<l||r<ql)return;
    	if(ql<=l&&r<=qr){lz[i]+=x,mx[i]+=x;return;}
    	int mid=(l+r)>>1;
    	update(i<<1,l,mid,ql,qr,x),update(i<<1|1,mid+1,r,ql,qr,x);
    	mx[i]=max(mx[i<<1],mx[i<<1|1])+lz[i];
    }
    inline bool cmp(node x,node y)
    {return x.y<y.y||(x.y==y.y&&x.x<y.x);}
    
    inline void solve()
    {
    	sort(p+1,p+n+1,cmp);
    	build(1,1,n),t1=t2=0;
    	for(int i=1;i<=n;i++)
    	{
    		if(i>1)update(1,1,n,i-1,i-1,W);
    		ans=max(ans,(p[i].y+mx[1]));
    		if(p[i].x<=W/2)
    		{
    			update(1,1,n,s1[t1],i-1,-p[i].x);
    			while(t1&&p[s1[t1]].x<p[i].x)update(1,1,n,s1[t1-1],s1[t1]-1,p[s1[t1]].x-p[i].x),--t1;
    			s1[++t1]=i;
    		}
    		else
    		{
    			update(1,1,n,s2[t2],i-1,p[i].x-W);
    			while(t2&&p[s2[t2]].x>p[i].x)update(1,1,n,s2[t2-1],s2[t2]-1,p[i].x-p[s2[t2]].x),--t2;
    			s2[++t2]=i;
    		}
    	}
    }
    
    int main()
    {
    	W=getint(),H=getint(),n=getint();
    	for(int i=1;i<=n;i++)p[i].x=getint(),p[i].y=getint();
    	p[++n]=(node){0,0},p[++n]=(node){W,H};
    	solve();
    	for(int i=1;i<=n;++i)swap(p[i].x,p[i].y);
    	swap(W,H);
    	solve();
    	printf("%d\n",ans*2); 
    }
    

  • 相关阅读:
    关于网购心态
    c++ In STL maps, is it better to use map::insert than []? Stack Overflow
    小工具:sshcopyid_老王的技术手册 ( 我的新博客:http://huoding.com )_百度空间
    djangoqbe
    C++ STL map的使用
    容器find_if函数定义和其第三个参数重载的疑问
    ArchLinux的安装与配置
    使用Grub进行Linux的硬盘安装与修复
    MySQL数据类型简介
    ArchLinux下Alsa的简单配置
  • 原文地址:https://www.cnblogs.com/IzayoiDoyo/p/13405994.html
Copyright © 2011-2022 走看看