游记
今天下午省选模拟打得我心态爆炸,晚上打打abc压压惊。
开场过了 5 5 分钟我才开始打,这让我成为了第一版(A题开局)A掉A题最慢的人了。
被wzy奶了一口AK,好像真AK了……
wzy:“abc的题目啥时候这么水了啊。”
垃圾abc,辛辛苦苦打个3rd才给我加这么点rating,以后再也不打abc了。
A - Add Sub Mul
题目大意
给出,求 a+b,a−b,a×b a + b , a − b , a × b 中的最大值。
思路
这……水了点吧。
B - Cut and Count
题目大意
给出一个字符串 S S ,长度,现在你可以把字符串分成两段,求分成两段后,两段中共有字母的最大个数。
例如,aabbca这个字符串,可以分成aab,bca两个串,共有字母为a和b,个数即为2。
思路
枚举断点,暴力统计答案即可。
C - Attention
题目大意
N N 个人从西向东站成一排,每个人朝向东或西,题目给出。现在要选取一个leader,使所有人都面向他(leader的朝向随意),求需要更改朝向的人的最小个数。
思路
需要更改朝向的人数,就是leader左侧朝向左和leader右侧朝向右的人数之和,而这两个显然可以对所有点同时 O(N) O ( N ) 的统计。
D - Xor Sum 2
题目大意
给定序列 A A ,长度为,求满足下面条件的 l,r l , r 个数:
Al+Al+1+⋯+Ar=Al xor Al+1 xor ⋯ xor Ar A l + A l + 1 + ⋯ + A r = A l x o r A l + 1 x o r ⋯ x o r A r
N≤2×105,Ai≤220 N ≤ 2 × 10 5 , A i ≤ 2 20
思路
满足条件,就是 l l 到中,枚举每个二进制位,这个二进制位为 1 1 的数的个数都要小于等于。
观察到,如果 l l 增加,对应最大的一定是单调递增的。可以用two-pointer解决。
代码
A - Add Sub Mul
#include <cstdio>
#include <algorithm>
int a,b;
int main()
{
scanf("%d%d",&a,&b);
printf("%d\n",std::max(std::max(a+b,a-b),a*b));
return 0;
}
B - Cut and Count
#include <cstdio>
#include <cstring>
const int maxn=100;
char s[maxn+2];
int have[2][30],ans,n;
int main()
{
scanf("%d%s",&n,s+1);
for(int i=1; i<n; ++i)
{
memset(have,0,sizeof have);
int cnt=0;
for(int j=1; j<=i; ++j)
{
have[0][s[j]-'a'+1]=1;
}
for(int j=i+1; j<=n; ++j)
{
have[1][s[j]-'a'+1]=1;
}
for(int j=1; j<=26; ++j)
{
if(have[0][j]&&have[1][j])
{
++cnt;
}
}
if(cnt>ans)
{
ans=cnt;
}
}
printf("%d\n",ans);
return 0;
}
C - Attention
#include <cstdio>
const int maxn=300000;
const int inf=0x3f3f3f3f;
char s[maxn+10];
int n,f[maxn+10],g[maxn+10],ans;
int main()
{
scanf("%d%s",&n,s+1);
for(int i=2; i<=n; ++i)
{
f[i]=f[i-1]+(s[i-1]=='W');
}
for(int i=n-1; i; --i)
{
g[i]=g[i+1]+(s[i+1]=='E');
}
ans=inf;
for(int i=1; i<=n; ++i)
{
if(f[i]+g[i]<ans)
{
ans=f[i]+g[i];
}
}
printf("%d\n",ans);
return 0;
}
D - Xor Sum 2
#include <cstdio>
const int maxn=200000;
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int n,a[maxn+10],t[maxn+10][23],now[23];
long long ans;
inline int trans(int v,int pos)
{
int x=1;
while(v)
{
t[pos][x]=v%2;
++x;
v/=2;
}
return 0;
}
inline int check(int pos)
{
for(int i=1; i<=20; ++i)
{
if(now[i]&&t[pos][i])
{
return 0;
}
}
return 1;
}
int main()
{
n=read();
for(int i=1; i<=n; ++i)
{
a[i]=read();
trans(a[i],i);
}
int r=1;
for(int i=1; i<=20; ++i)
{
now[i]=t[1][i];
}
for(int l=1; l<=n; ++l)
{
for(int i=1; i<=20; ++i)
{
now[i]^=t[l-1][i];
}
while((r<n)&&(check(r+1)))
{
++r;
for(int i=1; i<=20; ++i)
{
now[i]|=t[r][i];
}
}
ans+=r-l+1;
}
printf("%lld\n",ans);
return 0;
}