1 条题解

  • 1
    @ 2025-4-5 13:21:57

    既然我菜,那我就要努力(让自己更菜)

    既然我乱搞能A这题,那一定有人也能乱搞过这题

    悬线法

    应该来做这题的都学过这种算法了吧(笑 就是记录一个点向下延申多少会碰到障碍物

    题解

    于是这题就变得十分弱智了,就是悬线记录碰到障碍物的距离,与可以穿过一次障碍物的距离

    接着分类讨论即可,新意不多 枚举ii

    1. 当前选择不碰障碍物,两边延伸至[l2,r2][l2,r2],然后分别讨论l2+1l2+1r2+1r2+1是否可以选择带障碍物,再次延伸至l3l3r3r3,取[l2,r3][l2,r3][l3,r2][l3,r2]较长者乘上高度即可
    2. 当前选择碰障碍物,两边延伸至[l,r][l,r],直接乘上高度即可 由于碰到障碍物的距离总比穿过一次短,复杂度得到保证,总为O(ws)O(ws)

    于是题目到此为止

    但此题细节甚多,如必须采用stable_sortstable\_sort,否则会碰到野指针(我爱sortsort

    code

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2007;
    int w,s,a[N][N],b[N][N],ans,tp,st[N];
    int l[N],r[N],l2[N],r2[N],l3[N],r3[N];
    char p[N][N];
    int vt[N][N],sz[N];
    main(){
    	ios::sync_with_stdio(0);
    	cin.tie(),cout.tie();
    	cin>>w>>s;
    	for(int i=1;i<=w;i++)
    		cin>>(p[i]+1);
    	for(int j=1;j<=s;j++)
    		for(int i=w;i;i--){
    			if(p[i][j]=='#')
    				a[i][j]=0;
    			else
    				a[i][j]=a[i+1][j]+1;
    			b[i][j]=a[i][j]+1+a[i+a[i][j]+1][j];
    			if(i+a[i][j]==w+1)
    				b[i][j]=a[i][j];
    		}
    	for(int i=1;i<=w;i++){
    		tp=0,st[++tp]=0,a[i][0]=-1;l[0]=0;
    		for(int j=1;j<=s;j++){
    			while(a[i][st[tp]]>=b[i][j])--tp;
    			l[j]=st[tp];
    			while(a[i][st[tp]]>=a[i][j])--tp;
    			l2[j]=st[tp];
    			if(b[i][l2[j]]<a[i][j])l3[j]=l2[j];
    			else if(l2[j]!=0)vt[l2[j]][++sz[l2[j]]]=j;
    			else l3[j]=0;
    			st[++tp]=j;
    		}
    		tp=0,st[++tp]=0,a[i][0]=-1;l[0]=0;
    		for(int j=1;j<=s;j++){
    			stable_sort(vt[j]+1,vt[j]+sz[j]+1,[&](int x,int y){
    				return a[i][x]>=a[i][y];
    			});
    			for(int o=1;o<=sz[j];o++){
    				int p=vt[j][o];
    				while(a[i][st[tp]]>=a[i][p])--tp;
    				l3[p]=st[tp];
    			}
    			while(a[i][st[tp]]>=a[i][j])--tp;
    			st[++tp]=j;
    		}
    		for(int j=s;j;j--)sz[j]=0;
    		tp=0,st[++tp]=s+1,a[i][s+1]=-1;r[s+1]=s+1;
    		for(int j=s;j;j--){
    			while(a[i][st[tp]]>=b[i][j])--tp;
    			r[j]=st[tp];
    			while(a[i][st[tp]]>=a[i][j])--tp;
    			r2[j]=st[tp];
    			if(b[i][r2[j]]<a[i][j])r3[j]=r2[j];
    			else if(r2[j]!=s+1)vt[r2[j]][++sz[r2[j]]]=j;
    			else r3[j]=s+1;
    			st[++tp]=j;
    		}
    		tp=0,st[++tp]=s+1,a[i][s+1]=-1;
    		for(int j=s;j;j--){
    			stable_sort(vt[j]+1,vt[j]+sz[j]+1,[&](int x,int y){
    				return a[i][x]>=a[i][y];
    			});
    			for(int o=1;o<=sz[j];o++){
    				int p=vt[j][o];
    				while(a[i][st[tp]]>=a[i][p])--tp;
    				r3[p]=st[tp];
    			}
    			while(a[i][st[tp]]>=a[i][j])--tp;
    			st[++tp]=j;
    		}
    		for(int j=s;j;j--)sz[j]=0;
    		for(int j=1;j<=s;j++)
    			ans=max({ans,a[i][j]*(max(r3[j]-l2[j]-1,r2[j]-l3[j]-1)),b[i][j]*(r[j]-l[j]-1)});
    	}
    	cout<<ans<<endl;
    }
    

    信息

    ID
    3276
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    6
    已通过
    1
    上传者