Codeforces Round #789 div2

Round #789 (Div. 2)

A. Tokitsukaze and All Zero Sequence(签到)

思路:分类讨论:若序列中有 0 0 0 a n s = n − t t ( 0 ) ans=n-tt(0) ans=ntt(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,b1][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+=ans1ans2
预处理一个前缀和和后缀和即可

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懂又不懂啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值