Codeforces Round #852 (Div. 2)(C,D)
B
这个题大意是给你一个\(x\),\(y\),\(x\)是极大值(\(a_i>a_{i+1},a_i>a_{i+1}\))的和,
\(y\)是极小值(\(a_i<a_{i+1},a_i<a_{i+1}\))的和
然后还告诉我们每两个相邻的数相差\(1\),\(a_1\)和\(a_2\)和\(a_n\)
我们要求最短的一个数组满足这个和的条件
案例给出我们这个和是由多个数组成,其实这个也可以由一个数组成,那么我们只需要构造一个最高点\(x\),最低点\(y\),这样也是最短长度,其实我们不太需要考虑这么多,\(cf\)其实很多套路的
然后我直接构造即可
其实这次的\(B\)我还想了好久,看了题目案例,还以为需要考虑很多,想多了
C
这个题的大意是给你一个数组,我们有一个要求得到一对\(l\),\(r\),要求在\([l,r]\)这一段的数,其中所有的数的最大值和最小值不在两端,在中间,问有多少对这样的\(l\),\(r\)
我第一印象就是直接求,枚举\(l\)从\(1\)开始,\(r\)从\(n\)开始,\(l\)向右移动,\(r\)向左移动,如果满足条件就输出答案
#include <iostream>
using namespace std;
const int maxn=2e5+10;
#define int long long
int t;
int n;
int a[maxn];
void solve()
{
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>a[i];
}
if (n<=2)
{
cout<<-1<<'\n';
return ;
}
int step=1;
int l=1,r=n;
int mi=1,mx=n;
while (l<r)
{
int ll=l,rr=r;
while (a[l]==mi&&l<r)//只能一个一个移动,可能中间会出现可能的情况
{
l++;
mi++;
}
while (a[l]==mx&&l<r)
{
l++;
mx--;
}
while (a[r]==mi&&l<r)
{
r--;
mi++;
}
while (a[r]==mx&&l<r)
{
r--;
mx--;
}
if (l==ll&&r==rr) break;//这个就是l,r上不是最小值
}
if (r-l<=1) cout<<-1<<'\n';//不可以是两个相邻或者是长度为1的
else cout<<l<<" "<<r<<"\n";
return ;
}
signed main ()
{
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
D
这个题大意还是求\([l,r]\)这一段的\(p\)和\(q\)的\(mex\)是一样的的数量
我们只需要列举每一个\(mex\)的值,然后对于每一种\(mex\)的\(l\)和\(r\)都会有一个范围,然后直接求即可
具体看代码
#include <iostream>
#include <cmath>
using namespace std;
const int maxn=2e5+10;
#define int long long
int t,p[maxn],q[maxn],invp[maxn],invq[maxn],n;
void solve()
{
int ans=0;
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>p[i];
invp[p[i]]=i;
}
for (int i=1;i<=n;i++)
{
cin>>q[i];
invq[q[i]]=i;
}
int maxl=n+1,minr=0;
for (int mex=2;mex<=n+1;mex++)
{
minr=max(minr,max(invp[mex-1],invq[mex-1]));//r至少也要包括[1,mex-1]的数
maxl=min(maxl,min(invp[mex-1],invq[mex-1]));//l最大l是最小的那一个mex-1的位置,那么这个l,r的范围里面一定有[1,mex-1](p和q里面)
int maxr=n,minl=1;
if (mex<=n)
{
if (invp[mex]<maxl)
{
minl=max(minl,invp[mex]+1);//在后面一个,不可选mex
}
else
{
maxr=min(maxr,invp[mex]-1);//在前面面一个,不可选mex
}
if (invq[mex]<maxl)
{
minl=max(minl,invq[mex]+1);
}
else
{
maxr=min(maxr,invq[mex]-1);
}
}
if (minl<=maxl&&minr<=maxr)
{
ans+=(maxl-minl+1)*(maxr-minr+1);
}
}
int len=min(invp[1],invq[1])-1;//这个是mex=1的情况
ans+=len*(len+1)/2;
len=n-max(invp[1],invq[1]);
ans+=len*(len+1)/2;
len=abs(invp[1]-invq[1])-1;
ans+=len*(len+1)/2;
cout<<ans<<'\n';
return ;
}
signed main ()
{
int t=1;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
标签:852,int,Codeforces,long,maxn,Div,include,mex
From: https://www.cnblogs.com/righting/p/17116578.html