2020-3-21模拟赛题解

T1

直接模拟

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int x,y;
    cin>>x>>y;
    double ans;
    if(y==0){
        ans=10.0;
        if(x>3)ans+=1.0*(x-3.0)*2;
        if(x>15)ans+=1.0*(x-15.0);
    }else{
        ans=11.0;
        if(x>3)ans+=1.0*(x-3.0)*2;
        if(x>15)ans+=1.0*(x-15.0);
        ans+=(x-3)*0.4;
    }cout<<fixed<<setprecision(1)<<ans;
    return 0;
}

T2

我们发现一场比赛

  • 如果分出了胜负,所有球队的积分和增加 3 3
  • 如果没分出胜负,所有球队的积分和增加 2 2

所以,平局场数=比赛常数 × \times 3 - 所有球队的计分和

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int main(){
	int n,t,s=0,x;
	read(t);read(n);
	for(int i=1;i<=t;i++){
		read(x);
		s+=x;//算和
	}cout<<(3*n-s);//平局局数
	return 0;
}

T3

我傻,傻乎乎地写高精,只不过调得还满快的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
string p,q,r;
int x[1010],a[1010],b[1010];
char work(int x){
	if(x<=9)return char(x+48);
	return char(x+55);
}
int work2(char x){
	if(isdigit(x))return x-48;
	return x-55;
}
string jf(string st1,string st2,int t){
	memset(x,0,sizeof(x));
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
    string ans="";
    int k=-1,f=0,la,lb;
    for(int i=st1.size()-1;i>=0;i--){
        k++;
        a[k]=st1[i]-48;
    }la=st1.size();
    k=-1;
    for(int i=st2.size()-1;i>=0;i--){
        k++;
        b[k]=st2[i]-48;
    }lb=st2.size();
    for(int i=0;i<la;i++)
        for(int j=0;j<lb;j++)
            x[i+j]=x[i+j]+a[i]*b[j];
    for(int i=0;i<1000;i++){
        x[i+1]=x[i+1]+x[i]/t;
        x[i]=x[i]%t;
    }
    for(int i=1000;i>=0;i--)
        if(f)ans=ans+work(x[i]);
        else if(x[i]!=0){
                ans=ans+work(x[i]);
                f=1;
            }
    if(f==0)ans=ans+'0';
    return ans;
}
bool check(int x){
	if(jf(p,q,x)==r)return true;
	return false;
}
int main(){
	cin>>p>>q>>r;
	for(int i=2;i<=16;i++)
		if(check(i)){
			cout<<i;
			return 0;
		}
	cout<<0;
	return 0;
}

实际上,可以把 pqr 都转成 10 进制,看合不合法。

#include <bits/stdc++.h>
using namespace std;
int work(int x,string st){
	int ans=0;
    for(int i=0;i<st.size();i++)
    	if(st[i]-'0'>=x)return 0;//判断是否合法
        ans=ans*x+st[i]-'0';
    }return ans;
}
int main(){
	string p,q,r;
	cin>>p>>q>>r;
	for(int i=2;i<=16;i++){
		int p2=work(i,p),q2=work(i,q),r2=work(i,r);
		if(p2*q2==r2){
			cout<<i<<endl;
			return 0;
		}
	}puts("0");
	return 0;
}

T4

大模拟,不讲。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int>v;
int main(){
	v.push_back(0);
	int n,m,i;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		v.push_back(x);
	}
	for(i=1;i<=m;i++){
		int x,y;
		cin>>x>>y;
		v.insert(v.begin()+y+1,x);
		y++;
		int l=y,r=y;
		while(v[l-1]==v[y]&&l-1>0)l--;
		while(v[r+1]==v[y]&&r+1<v.size())r++;
		if(r-l>1){
			for(int j=l;j<=r;j++)v.erase(v.begin()+l);
			y=l-1;
		}
		while(v.size()>2){
			int l=y,r=y;
			while(v[l-1]==v[y]&&l-1>0)l--;
			while(v[r+1]==v[y]&&r+1<v.size())r++;
			if(r-l+1<3||r==y)break;
			else{
				v.erase(v.begin()+l,v.begin()+r+1);
				y=l-1;
			}
		}
	}cout<<v.size()-1;
	return 0;
}

T5

搜索

这是最基本的搜索。有 40 40 分。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k;
int dfs(int n,int k){
	if(k==1)return n;
	int ans=INT_MAX;
	for(int i=1;i<=n;i++){
		if(n%i==0)ans=min(ans,min(i+dfs(n/i,k-1),n/i+dfs(i,k-1)));
	}return ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(n,k);
	return 0;
}

之后,有 2 2 种方法,先介绍第 1 1 种。

1 1

这个是标程的方法,最终效果会比我的方法慢,但是代码极为简短。

首先,对于上面的代码,可以加上记忆化。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k;
map<int,map<int,int> >mp;
int dfs(int n,int k){
	if(k==1)return n;
	if(mp[n][k])return mp[n][k];
	int ans=INT_MAX;
	for(int i=1;i<=n;i++){
		if(n%i==0)ans=min(ans,min(i+dfs(n/i,k-1),n/i+dfs(i,k-1)));
	}return mp[n][k]=ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(n,k);
	return 0;
}

依旧只有 40 40 分。

继续优化,我们发现枚举约数可以优化。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k;
map<int,map<int,int> >mp;
int dfs(int n,int k){
	if(k==1)return n;
	if(mp[n][k])return mp[n][k];
	int ans=INT_MAX;
	for(int i=1;i*i<=n;i++){
		if(n%i==0)ans=min(ans,min(i+dfs(n/i,k-1),n/i+dfs(i,k-1)));
	}return mp[n][k]=ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(n,k);
	return 0;
}

这样就有 80 80 分了。

还可以在哪里优化呢?

我们发现 k k 很大,而 n n 的质因子个数并不多。

可以证明(显然) n n 的质因子小于 log n \log {n}

那么 k k 这么大,显然就是有很多很多的 1 1

可以让i 2 2 开始。

Q:如果是质数怎么办?返回INT_MAX显然是错的。

A:所以我们需要把ans的初值赋成n+k-1

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k;
map<int,map<int,int> >mp;
int dfs(int n,int k){
	if(k==1)return n;
	if(mp[n][k])return mp[n][k];
	int ans=n+k-1;
	for(int i=2;i*i<=n;i++){
		if(n%i==0)ans=min(ans,min(i+dfs(n/i,k-1),n/i+dfs(i,k-1)));
	}return mp[n][k]=ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(n,k);
	return 0;
}

这样就有100分了。

最大的点跑了0.234s

2 2

我们先增加一个参数l,让后面的数字全部要 \geq l

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k;
ll dfs(int l,int n,int k){
	if(k==1)return n;
	ll ans=INT_MAX;//可能会炸出负数,所以要long long
	for(int i=l;i<=n;i++){
		if(n%i==0)ans=min(ans,i+dfs(i,n/i,k-1));
	}return ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(1,n,k);
	return 0;
}

依旧只有 40 40 分。

继续优化,我们发现可以加记忆化。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
map<int,map<int,map<int,int> > >mp;
int n,k;
ll dfs(int l,int n,int k){
	if(k==1)return n;
	if(mp[l][n][k])return mp[l][n][k];
	ll ans=INT_MAX;
	for(int i=l;i<=n;i++){//这里
		if(n%i==0)ans=min(ans,i+dfs(i,n/i,k-1));
	}return mp[l][n][k]=ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(1,n,k);
	return 0;
}

依旧是 40 40 q w q qwq 。。。

继续优化,我们发现枚举约数可以优化。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k;
ll dfs(int l,int n,int k){
	if(k==1)return n;
	ll ans=INT_MAX;
	for(int i=l;i*i<=n;i++){
		if(n%i==0)ans=min(ans,i+dfs(i,n/i,k-1));
	}return ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(1,n,k);
	return 0;
}

这样就有 80 80 分了。

还可以在哪里优化呢?

我们发现 k k 很大,而 n n 的质因子个数并不多。

可以证明(显然) n n 的质因子小于 log n \log {n}

那么 k k 这么大,显然就是有很多很多的 1 1

我们可以让l 2 2 开始。

Q:如果是质数怎么办?返回INT_MAX显然是错的。

A:所以我们需要把ans的初值赋成n+k-1

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k;
ll dfs(int l,int n,int k){
	if(k==1)return n;
	ll ans=n+k-1;
	for(int i=l;i*i<=n;i++){
		if(n%i==0)ans=min(ans,i+dfs(i,n/i,k-1));
	}return ans;
}
int main(){
	read(n);read(k);
	cout<<dfs(2,n,k);
	return 0;
}

这样就有100分了。

最大的点跑了0.093s

也算是一个很大的突破。

Q:还有哪里可以优化吗?

A:其实还是有的。

我们看 d f s dfs 里的 i i 。由于 i i 是保证单调不下降的,所以 i k n i^{k}\leq n

这样的话,我们可以用到快速幂的方法。

但是,你会发现,这个是假的,因为我们把 1 放到了最后处理,所以此优化和上面的优化不可兼用,我们把上面的优化拿掉。

当然,因为 k k 过大,我们还得压缩一下 k k 的范围。

七七八八的优化搞到最后,代码差不多是这样的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
ll n,k,x=1,L=1,R=35,s;
ll pw(ll x,ll y){
	ll ans=1;
	while(y){
		if(y&1)ans=ans*x;
		y>>=1;
		x=x*x;
	}return ans;
}
map<int,map<int,map<int,int> > >mp;
ll dfs(ll l,ll n,ll k){
	if(k==1)return n;
	if(n==1)return k;
	if(mp[l][n][k])return mp[l][n][k];
	ll ans=INT_MAX;
	ll Lft=l-1,Rgt=10000;
	while(Lft+1<Rgt){
		ll Mid=(Lft+Rgt)>>1;
		if(pow(Mid,k)<=n)Lft=Mid;
		else Rgt=Mid;
	}
	for(ll i=l;i<=Lft;i++){
		if(n%i==0)ans=min(ans,i+dfs(i,n/i,k-1));
	}return mp[l][n][k]=ans;
}
int main(){
	read(n);read(k);
	int x=n;
	for(int i=2;i*i<=n;i++)
		while(x%i==0)x/=i,s++;
	if(x)s++;
	if(k>s)cout<<dfs(1ll,n,s)+k-s;
	else cout<<dfs(1ll,n,k);
	return 0;
}

最大的点跑了0.106s

当然最后的用时也差不多。

实际上,我们问题想回来,如果 k k 过于大,方法肯定是唯一的。

因为 x , y 2 x,y \geq 2 的情况下 x × y x + y x \times y \geq x+y 。所以,最优解显然是 n n 的质因子和 + + ( k (k - n n 的质因子个数 ) )

我们可以这样写一下。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
int n,k,s;
int pw(int x,int y){
	int ans=1;
	while(y){
		if(y&1)ans=ans*x;
		y>>=1;
		x=x*x;
	}return ans;
}
map<int,map<int,map<int,int> > >mp;
int dfs(int l,int n,int k){
	if(k==1)return n;
	if(mp[l][n][k])return mp[l][n][k];
	int ans=n+k-1,Lft=l-1,Rgt=100;
	while(Lft+1<Rgt){//这边的话,明显是有二分性的,所以直接二分。
		ll Mid=(Lft+Rgt)>>1;
		if(pow(Mid,k)<=n)Lft=Mid;
		else Rgt=Mid;
	}
	for(int i=l;i<=Lft;i++){//就不要一个一个去pow了
		if(n%i==0)ans=min(ans,i+dfs(i,n/i,k-1));
	}return mp[l][n][k]=ans;
}
int main(){
	vector<int>v;
	read(n);read(k);
	int x=n;
	for(int i=2;i*i<=n;i++)
		while(x%i==0)x/=i,s+=i,v.push_back(i);
	if(x)s+=x,v.push_back(x);
	if(k>=v.size())cout<<s+k-v.size();//就是上面的式子
	else cout<<dfs(2ll,n,k);//2个优化一起来
	return 0;
}

最慢的点跑了0.015s

我觉得这应该就是最优解了吧。

T6

我们去枚举 k k ,然后贪心去check

复杂度 O ( n 3 ) O(n^3)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
template<typename T>inline void write(T x){
	if(x<0)putchar('-'),x*=-1;
	if(x>9)write(x/10);
	putchar(x%10+48);
}
template<typename T>inline void writen(T x){
	write(x);
	puts("");
}
int n,a[3010],ans=INT_MAX,xi,b[3010];
queue<int>q;
int work(int x){
	for(int i=1;i<=n;i++)b[i]=a[i];
	int s=0;
	for(int i=1;i<=n;i++){
		if(b[i]%2==1){
			if(i+x-1>n)return INT_MAX;
            for(int i=1;i<k;i++)b[i+k]^=1;
			s++;
		}
	}return s;
}
int main(){
	read(n);
	for(int i=1;i<=n;i++)read(a[i]);
	for(int i=1;i<=n;i++){
		int x=work(i);
		if(x<ans){
			xi=i;
			ans=x;
		}
	}cout<<xi;
	return 0;
}

这样就有90分了。

100分做法有2种。都是去优化上述算法给后面数加的浪费时间的问题。

  • 可以差分
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
template<typename T>inline void write(T x){
	if(x<0)putchar('-'),x*=-1;
	if(x>9)write(x/10);
	putchar(x%10+48);
}
template<typename T>inline void writen(T x){
	write(x);
	puts("");
}
int n,a[3010],ans=INT_MAX,xi,b[3010];
queue<int>q;
int work(int x){
	memset(b,0,sizeof(b));
	int s=0;
	for(int i=1;i<=n;i++){
		b[i]+=b[i-1];
		if((b[i]+a[i])%2==1){
			if(i+x-1>n)return INT_MAX;
			b[i]++;
            b[i+x]--;
			s++;
		}
	}return s;
}
int main(){
	read(n);
	for(int i=1;i<=n;i++)read(a[i]);
	for(int i=1;i<=n;i++){
		int x=work(i);
		if(x<ans){
			xi=i;
			ans=x;
		}
	}cout<<xi;
	return 0;
}
  • 可以用单调队列
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
template<typename T>inline void write(T x){
	if(x<0)putchar('-'),x*=-1;
	if(x>9)write(x/10);
	putchar(x%10+48);
}
template<typename T>inline void writen(T x){
	write(x);
	puts("");
}
int n,a[3010],ans=INT_MAX,xi,b[3010];
queue<int>q;
int work(int x){
	while(q.size())q.pop();
	int s=0;
	for(int i=1;i<=n;i++){
		while(q.size()&&i-q.front()>=x)q.pop();
		if((a[i]+q.size())%2==1){
			if(i+x-1>n)return INT_MAX;
			s++,q.push(i);
		}
	}return s;
}
int main(){
	read(n);
	for(int i=1;i<=n;i++)read(a[i]);
	for(int i=1;i<=n;i++){
		int x=work(i);
		if(x<ans){
			xi=i;
			ans=x;
		}
	}cout<<xi;
	return 0;
}

T7

这道题,我们可以想一下,矩形的面积跟 2 2 条边有关。

对于每个点,我们算出 3 3 个数,lftrgtup

lft:即此点最多能向左延伸到哪一列。(初值为j)

for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
		if(a[i][j]&&a[i][j-1])lft[i][j]=lft[i][j-1];

rgt:即此点最多能向右延伸多少哪一列。(初值为j)

for(int i=1;i<=n;i++)
		for(int j=m;j>=1;j--)
			if(a[i][j]&&a[i][j+1])rgt[i][j]=rgt[i][j+1];

up:即此点最多能向上延伸多少个格子数。(初值为1)

d p dp 边求。

现在我们就说说 d p dp 吧。

for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++){
		if(a[i][j]&&a[i-1][j]){
			lft[i][j]=max(lft[i-1][j],lft[i][j]);//在up最优的情况下,左端点的距离要更新
			rgt[i][j]=min(rgt[i-1][j],rgt[i][j]);//在up最优的情况下,右端点的距离要更新
			up[i][j]=up[i-1][j]+1;
		}
		int x=rgt[i][j]-lft[i][j]+1;
		ans=max(ans,x*up[i][j]);
	}

其实就是找高度最高的矩形,为什么这样是正确的呢。

我们可以这样想一下。我们的算法本质就是, i , j i,j 最多往上的长度做矩阵一条边,这个就是 u p i , j up_{i,j} 干的事情,然后 l f t i , j lft_{i,j} r g t i , j rgt_{i,j} 则是要在 u p i , j up_{i,j} 最优的情况下,让另一条边也最优。

你可以再想一下,下面这张图,最大子矩阵是橙色方框圈起来的。我们可以发现,最大子矩阵的四条边,每条边要么是靠到边界,要么是靠到障碍物。也就是说,最大子矩阵的上边界一定会靠到障碍物或边界。我们的算法就相当于确定了下边界,然后用 u p up 数组又确定了上边界。然后用 l f t lft r g t rgt 确定左边界和右边界。213.png

如果还是不懂的话,可以再想一下,我来模拟一下。

这就是我们 u p up 做的事。

213.png

然后呢,对于每条线,我们要让他们的上边界尽可能的长。

213.png

再回来看看代码:

#include <bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
template<typename T>void write(T x){
	if(x<0)putchar('-'),x*=-1;
	if(x>9)write(x/10);
	putchar(x%10+48);
}
int a[2010][2010],lft[2010][2010],rgt[2010][2010],up[2010][2010],ans;
int main(){
	int n,m;
	read(n);read(m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			read(a[i][j]);
			a[i][j]^=1;
			lft[i][j]=j;
			rgt[i][j]=j;
			up[i][j]=1;
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]&&a[i][j-1])lft[i][j]=lft[i][j-1];
	for(int i=1;i<=n;i++)
		for(int j=m;j>=1;j--)
			if(a[i][j]&&a[i][j+1])rgt[i][j]=rgt[i][j+1];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			if(a[i][j]&&a[i-1][j]){
				lft[i][j]=max(lft[i-1][j],lft[i][j]);
				rgt[i][j]=min(rgt[i-1][j],rgt[i][j]);
				up[i][j]=up[i-1][j]+1;
			}
			int x=rgt[i][j]-lft[i][j]+1;
			ans=max(ans,x*up[i][j]);
		}
	write(ans);
	return 0;
}

是不是就懂了 q w q qwq 。。。

我才不告诉你,这个其实就是单调队列

发布了110 篇原创文章 · 获赞 188 · 访问量 7140

猜你喜欢

转载自blog.csdn.net/qq_46230164/article/details/105457851
今日推荐