文章目录
A. Tokitsukaze and All Zero Sequence(签到)
思路:分类讨论:若序列中有
0
0
0,
a
n
s
=
n
−
t
t
(
0
)
ans=n-tt(0)
ans=n−tt(0);若序列中有相同的数,
a
n
s
=
n
ans=n
ans=n;否则
a
n
s
=
n
+
1
ans=n+1
ans=n+1
注意多组查询每次清空计数数组
C o d e : Code: Code:
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl '\n'
#define y1 yyy
typedef long long ll;
typedef pair<int,int> PII;
const int N=1e6+10,mod=998244353;
int t,n,a[N],b[N];
void solve(){
cin>>n;
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) b[a[i]]++;
if(b[0]) {
cout<<n-b[0]<<endl;
return;
}
int tt=0,f=0;
for(int i=0;i<=100;i++){
if(b[i]>=2) f=1;
}
if(f) cout<<n<<endl;
else cout<<n+1<<endl;
}
int main(){
cin>>t;
while(t--){
solve();
}
return 0;
}
B2. Tokitsukaze and Good 01-String (hard version)(贪心)
思路:对于每一对相邻且不等的字符,把它们都变成
0
0
0或者都变成
1
1
1 。因此,将字符串分成许多相邻的长度为
2
2
2的二元组,若二元组为"01"或"10"则需要
1
1
1的操作次数,否则不需要操作次数。若要"连续段"的数量最小,对于每个
01
01
01或者
10
10
10,将其变成和上一个或者下一个相同的
11
11
11或
00
00
00。
例如:“0010"变成"0000”,“1101"变成"1111”。这种子段对最终的连续段数量是没有任何贡献的。因此我们只需要统计有多少连续的
11
11
11二元组
和
00
00
00二元组即可。特殊的,如果所有二元组均为"01"或"10",最终对最终连续段的数量总共有
1
1
1的贡献
C o d e : Code: Code:
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl '\n'
#define y1 yyy
typedef long long ll;
typedef pair<int,int> PII;
const int N=1e6+10,mod=998244353;
int n;
char a[N];
void solve(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
char pre='a';
int x=0,y=0;
for(int i=1;i<n;i+=2){
if(a[i]!=a[i+1])x++;
else{
if(pre!=a[i]) y++;
pre=a[i];
}
}
cout<<x<<" "<<max(1,y)<<endl;
}
int main(){
int t;cin>>t;
while(t--){
solve();
}
return 0;
}
C. Tokitsukaze and Strange Inequality(枚举+前缀和)
思路:首先把问题转化为在二维平面上找满足条件的点对的数量
枚举
b
b
b和
c
c
c,那么问题转化成中在
[
1
,
b
−
1
]
[
1
,
p
[
c
]
−
1
]
[1,b-1][1,p[c]-1]
[1,b−1][1,p[c]−1]和
[
c
+
1
,
n
]
[
1
,
p
[
b
]
−
1
]
[c+1,n][1,p[b]-1]
[c+1,n][1,p[b]−1]的点的个数
a
n
s
1
ans1
ans1和
a
n
s
2
ans2
ans2,
a
n
s
+
=
a
n
s
1
∗
a
n
s
2
ans+=ans1*ans2
ans+=ans1∗ans2
预处理一个前缀和和后缀和即可
C o d e : Code: Code:
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl '\n'
#define y1 yyy
typedef long long ll;
typedef pair<int,int> PII;
const int N=5e3+10,mod=998244353;
int s1[N][N],t,n,p[N],s2[N][N];
void solve(){
cin>>n;
for(int i=0;i<=n+2;i++){
for(int j=0;j<=n+2;j++){
s1[i][j]=s2[i][j]=0;
}
}
for(int i=1;i<=n;++i){
cin>>p[i];
s1[i][p[i]]++;
s2[i][p[i]]++;
}
for(int i=1;i<=n+1;i++){
for(int j=1;j<=n+1;j++){
s1[i][j]+=s1[i-1][j]+s1[i][j-1]-s1[i-1][j-1];
}
}
for(int i=n+1;i>=1;i--){
for(int j=1;j<=n+1;j++){
s2[i][j]+=s2[i+1][j]+s2[i][j-1]-s2[i+1][j-1];
}
}
ll ans=0;
for(int b=2;b<n;b++){
for(int c=b+1;c<n;c++){
ans+=s1[b-1][p[c]-1]*s2[c+1][p[b]-1];
}
}
cout<<ans<<endl;
}
int main(){
IOS;
cin>>t;
while(t--){
solve();
}
return 0;
}