Codeforces Round 911 (Div. 2)

Codeforces Round 911 (Div. 2)

A - Cover in Water

思路:发现若有连续的三个...,可以通过两次操作将两边的水填满,对于中间的位置自动产水再移走去填补其他空,那么只需要两次

其余的情况则需要一一操作填满空

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;


void solve(){
    int n;
    string s;
    cin>>n>>s;
    int ma=0,cnt=0,all=0;
    for(int i=0;i<n;++i){
        if(s[i]=='.')cnt++,ma=max(ma,cnt),all++;
        else cnt=0;
    }
    if(ma>=3)cout<<2<<'\n';
    else cout<<all<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

B - Laura and Operations

思路:若全转变为a,假设b>=c,可先对b、c操作c次,三个数变为a+c、b-c、0,可以通过进行 减ab加c 和 减bc从加a 两次操作使得三个数变为a+c、b-c-2、0,那么只需要判断b-c是否为偶数即可,全转变为a或b或c都是同理

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;


void solve(){
    int a,b,c;
    vector<int>ans(3,0);
    cin>>a>>b>>c;
    if(abs(b-c)%2==0)ans[0]=1;
    if(abs(a-c)%2==0)ans[1]=1;
    if(abs(a-b)%2==0)ans[2]=1;
    for(int i=0;i<3;++i)cout<<ans[i]<<' ';
    cout<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

C - Anji's Binary Tree

思路:从根节点dfs跑一次,可以剪下枝,当前次数已经大于答案了就不用继续了

或者dp维护从i到达叶子节点需要的最少次数

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int n,ans,tes;
string s;
vector<vector<int>>ve;
vector<int>out;
void dfs(int u){
    if(tes>=ans)return;
    if(!out[u]){
        ans=min(ans,tes);
        return ;
    }
    if(ve[u][0]){
        if(s[u]!='L'){
            tes++;
            dfs(ve[u][0]);
            tes--;
        }else dfs(ve[u][0]);
    }
    if(ve[u][1]){
        if(s[u]!='R'){
            tes++;
            dfs(ve[u][1]);
            tes--;
        }else dfs(ve[u][1]);
    }
}
void solve(){
//    int n;
//    string s;
    ans=INF;
    cin>>n>>s;
    s=" "+s;
    ve=vector<vector<int>>(n+1,vector<int>(2));
    out=vector<int>(n+1);
    for(int i=1;i<=n;++i){
        cin>>ve[i][0]>>ve[i][1];
        out[i]+=(int)(ve[i][0]!=0)+(int)(ve[i][1]!=0);
    }
    tes=0;
    dfs(1);
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

D - Small GCD

思路:求Σf(ai,aj,ak),其实就是所有gcd(ai,aj)的贡献,那么ijk的顺序就不重要了,首先可以将a排序。

可以枚举j,求出Σgcd(ai,aj),i<j,且k的个数等于Σgcd(ai,aj)贡献的次数,那么答案就是Σgcd(ai,aj)*(n-i),i<j

考虑到复杂度,怎么求Σgcd(ai,aj),i<j 呢?


 

引入欧拉反演

 

 

 


 

 

n/d表示n以内的数中为d的倍数的数量,在本题中可以维护a1~ai的所有数中为d的倍数的数量cnt[d]

则有

 

 

 

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;
int cnt,primes[N],phi[N];
bool st[N];
int n;
void get_phi(int n){
    phi[1]=1;
    for(int i=2;i<=n;++i){
        if(!st[i])phi[i]=i-1,primes[cnt++]=i;
        for(int j=0;primes[j]*i<=n;++j){
            int t=i*primes[j];
            st[t]=true;
            if(i%primes[j]==0){
                phi[t]=phi[i]*primes[j];
                break;
            }
            else phi[t]=phi[i]*(primes[j]-1);
        }
    }
}

void solve(){
    cin>>n;
    vector<int>a(n+1),num(N);
    for(int i=1;i<=n;++i)cin>>a[i];
    sort(a.begin()+1,a.end());
    int ans=0;
    for(int i=1;i<n;++i){
        int s=0,x=a[i];
        for(int j=1;j*j<=x;++j){
            if(x%j)continue;
            s+=phi[j]*num[j]++;
            if(j*j!=x)s+=phi[x/j]*num[x/j]++;
        }
        ans+=s*(n-i);
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    get_phi(100000);
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

posted @ 2023-11-28 02:21  bible_w  阅读(24)  评论(0编辑  收藏  举报