Codeforces Round #549题解

A题

计算每组最后出现的那个取min

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    for(i=1;i<=n;i++){
        cin>>a[i];
    }
    int cnt1=0,cnt2=0;
    for(i=1;i<=n;i++){
        if(a[i]==1)
            cnt1=i;
        else
            cnt2=i;
    }
    cout<<min(cnt1,cnt2)<<endl;
    return 0;
}
View Code

B题

这题有数位dp控制最高位那味,如果最高位不受限

那么后面全取9,因此对每一位都做一下这个判断即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
int a[N];
ll pre[N];
int main(){
    ios::sync_with_stdio(false);
    ll n;
    int i,j;
    cin>>n;
    int cnt=0;
    while(n){
        a[++cnt]=n%10;
        n/=10;
    }
    if(cnt==1){
        cout<<a[1]<<endl;
        return 0;
    }
    pre[0]=1;
    for(i=1;i<=20;i++){
        pre[i]=pre[i-1]*9;
    }
    reverse(a+1,a+1+cnt);
    ll ans=1;
    ll mx=1;
    for(i=1;i<=cnt;i++){
        ans=ans*a[i];
    }
    for(i=1;i<=cnt;i++){
        ll tmp=a[i]-1;
        if(a[i]==1){
            tmp=1;
        }
        for(j=1;j<i;j++){
            tmp*=a[j];
        }
        for(j=i+1;j<=cnt;j++)
            tmp*=9;
        ans=max(ans,tmp);
    }
    cout<<ans<<endl;
    return 0;
}
View Code

C题

过于水,记录三个数组判断一下就行

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
int h[N],ne[N],e[N],idx;
int in[N],num[N];
int vis[N];
void add(int a,int b){
}
int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int i;
    for(i=1;i<=n;i++){
        int a,b;
        cin>>a>>b;
        if(a==-1){
            continue;
        }
        in[a]++;
        vis[i]=b;
        num[a]+=b;
    }
    int flag=0;
    for(i=1;i<=n;i++){
        if(vis[i]&&(in[i]==num[i])){
            cout<<i<<" ";
            flag=1;
        }
    }
    if(!flag){
        cout<<-1;
    }
    cout<<endl;
    return 0;
}
View Code

D题

起点在哪其实无所谓,那么我们假定0点为对于起点最近的那个,这样就有两种情况,一种是起点后a,一种是起点前a,那么对于b也是两种情况,不同的是,b可以是每个点的前后差值,因此枚举每种情况取最值即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,int> plll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
int main(){
    ios::sync_with_stdio(false);
    ll n,k;
    ll a,b;
    cin>>n>>k>>a>>b;
    ll ans=0;
    ll res=1e18;
    ll tmpa=a;
    ll i;
    for(i=0;i<=(n-1)*k;i+=k){
        ll tmpb=(i-b+n*k)%(n*k);
        ll d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
        tmpb=(i+b+n*k)%(n*k);
        d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
    }
    tmpa=(-a+n*k)%(n*k);
    for(i=0;i<=(n-1)*k;i+=k){
        ll tmpb=(i-b+n*k)%(n*k);
        ll d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
        tmpb=(i+b+n*k)%(n*k);
        d=(tmpb-tmpa+n*k)%(n*k);
        ans=max(ans,n*k/gcd(d,n*k));
        res=min(res,n*k/gcd(d,n*k));
    }
    cout<<res<<" "<<ans<<endl;
    return 0;
}
View Code

 E题

没有想到做法,没想到倍增的思路。

我们发现对于每个pi,前面的数都是固定的

因此我们对于ai,计算以他为结尾的序列,这样可以根据他最近的前面的那个数,用倍增的思路,计算他跳n-1次的最晚出现位置

这样再用一次倍增维护区间max,直接求解区间最值是否大于l即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=2e5+10;
const int mod=998244353;
const int inf=0x3f3f3f3f;
int p[N],pre[N];
int a[N],lg[N];
int f[N][27];
int g[N][27];
int lst[N];
void init(){
    lg[1]=0;
    lg[2]=1;
    for(int i=3;i<=200000;i++){
        lg[i]=lg[i>>1]+1;
    }
}
int get(int l,int r){
    int k=lg[r-l+1];
    return max(g[l][k],g[r-(1<<k)+1][k]);
}
int main(){
    ios::sync_with_stdio(false);
    int n,m,q;
    cin>>n>>m>>q;
    int i;
    init();
    for(i=1;i<=n;i++){
        cin>>p[i];
    }
    for(i=1;i<=m;i++){
        cin>>a[i];
    }
    p[0]=p[n];
    for(i=1;i<=n;i++){
        pre[p[i]]=p[i-1];
    }
    for(i=1;i<=m;i++){
        f[i][0]=lst[pre[a[i]]];
        lst[a[i]]=i;
    }
    for(i=1;i<=25;i++){
        for(int j=1;j<=m;j++){
            f[j][i]=f[f[j][i-1]][i-1];
        }
    }
    for(i=1;i<=m;i++){
        g[i][0]=i;
        for(int j=0;j<=lg[n-1];j++){
            if((n-1)&(1<<j)){
                g[i][0]=f[g[i][0]][j];
            }
        }
    }
    for(i=1;i<=lg[m];i++){
        for(int j=1;j+(1<<i)-1<=m;j++){
            g[j][i]=max(g[j][i-1],g[j+(1<<i-1)][i-1]);
        }
    }
    string s="";
    while(q--){
        int l,r;
        cin>>l>>r;
        if(get(l,r)>=l){
            s+='1';
        }
        else{
            s+='0';
        }
    }
    cout<<s<<endl;
}
View Code

 

posted @ 2020-12-27 19:06  朝暮不思  阅读(52)  评论(0编辑  收藏  举报