Educational Codeforces Round 185 (Rated for Div. 2) A,B,C,E,D

A. Maximum Neighborhood

直接暴力构造出矩阵然后枚举答案,反正能过

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
	int n;
    cin>>n;

    vector<vector<int>> a(n+2,vector<int>(n+2));

    int now=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            a[i][j]=now++;
        }
    }

    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            ans=max(ans,a[i][j]+a[i-1][j]+a[i][j-1]+a[i+1][j]+a[i][j+1]);
        }
    }

    cout<<ans<<endl;
}
	
signed main(){

	ios::sync_with_stdio(0);
	cin.tie(0);

	int t=1;
	cin>>t; 
	
	while(t--){
		solve(); 
	}

}

B. Addition on a Segment

先剔除掉 \(b\) 中所有的 \(0\) 元素(因为完全没用),设此时 \(b\) 的大小为 \(n\)

答案最大肯定是 \(n\),最小代价肯定是对 \(n\) 个数每个数 \(+1\),这一步的消耗是 \(n\)

\(b\) 数组的总和为 \(sum\),做完上一步后,还要进行 \(n-1\) 次,如果 \(n-1<=sum-n\),则上一步可以正常进行

否则否则需要从第一步的 \(n\) 个中匀一些出去给剩下的 \(n-1\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
	int n;
    cin>>n;

    vector<int> a(n+1);
    int sum=0;
    int ans;
    vector<int> b;

    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]) b.push_back(a[i]);
        sum+=a[i];
    }

    ans=b.size();
    if(sum-ans>=n-1) cout<<ans<<endl;
    else{
        cout<<ans-(n-1-(sum-ans))<<endl;
    }


}
	
signed main(){

	ios::sync_with_stdio(0);
	cin.tie(0);

	int t=1;
	cin>>t; 
	
	while(t--){
		solve(); 
	}

}

C. Quotient and Remainder

\(a,b\) 中,任选两个数 \(va,vb\),可以得到一对最小的 \(x,y\) 是:

x=(vb+1)*va+vb;
y=vb+1;

所以可以从小到大枚举 \(b\),从大到小枚举 \(a\),为每个 \(b\) 找到一个尽可能大的 \(a\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

void solve(){
	int n,k;
    cin>>n>>k;

    vector<int> a(n+1),b(n+1);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }

    for(int i=1;i<=n;i++){
        cin>>b[i];
    }

    int cnt=0;

    sort(a.begin()+1,a.end());
    sort(b.begin()+1,b.end(),greater<int>());

    while(a.size()>1 && b.size()>1){
        int vb=b.back();
        int va=a.back();

        int x=(vb+1)*va+vb;
        int y=vb+1;

        if(x>=1 && x<=k && y>=1 && y<=k){
            b.pop_back();
            cnt++;
        }
        a.pop_back();
    }

    cout<<cnt<<endl;
}
	
signed main(){

	ios::sync_with_stdio(0);
	cin.tie(0);

	int t=1;
	cin>>t; 
	
	while(t--){
		solve(); 
	}

}

E. Binary Strings and Blocks

对于一对 \(l,r\),当且仅当整个区间全相等时,区间是不美丽的

\(b[i]=(s[i]!=s[i+1])\),等价于: \(b[l]\)\(b[r-1]\) 中,不全等于 \(0\) 时,\(l,r\) 是美丽的

\(lim[i]\) 表示,对于位置 \(i\),前面所有约束的最大值。

即上一个 \(b[j]=1\) 的位置必须要大于等于 \(lim[i]\),才能满足所有 \(r<=i\) 的约束

\(dp[i]\) 表示:考虑前 \(i\) 个字符,满足所有 \(r<=i\) 的约束的字符串方案数

所以最后一个 \(b[i]=1\) 的位置可以是 \(lim[i]\)\(i-1\)

所以 \(dp[i]=\sum_{j=\text{lim}[i]}^{\,i-1} dp[j]\)

数据结构或前缀和维护都行,前缀和维护 \(dp\) 很好写

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;

/*支持define int long long 的自动取模类*/
template<const int T>
struct ModInt {
    const static int mod = T;
    int x;
    ModInt(signed x = 0) : x(x % mod) {}
    ModInt(long long x) : x((int)x % mod) {} 
    int val() { return x; }
    ModInt operator + (const ModInt &a) const { int x0 = x + a.x; return ModInt(x0 < mod ? x0 : x0 - mod); }
    ModInt operator - (const ModInt &a) const { int x0 = x - a.x; return ModInt(x0 < 0 ? x0 + mod : x0); }
    ModInt operator * (const ModInt &a) const { return ModInt(1LL * x * a.x % mod); }
    ModInt operator / (const ModInt &a) const { return *this * a.inv(); }
    bool operator == (const ModInt &a) const { return x == a.x; };
    bool operator != (const ModInt &a) const { return x != a.x; };
    void operator += (const ModInt &a) { x += a.x; if (x >= mod) x -= mod; }
    void operator -= (const ModInt &a) { x -= a.x; if (x < 0) x += mod; }
    void operator *= (const ModInt &a) { x = 1LL * x * a.x % mod; }
    void operator /= (const ModInt &a) { *this = *this / a; }
    friend ModInt operator + (int y, const ModInt &a){ int x0 = y + a.x; return ModInt(x0 < mod ? x0 : x0 - mod); }
    friend ModInt operator - (int y, const ModInt &a){ int x0 = y - a.x; return ModInt(x0 < 0 ? x0 + mod : x0); }
    friend ModInt operator * (int y, const ModInt &a){ return ModInt(1LL * y * a.x % mod);}
    friend ModInt operator / (int y, const ModInt &a){ return ModInt(y) / a;}
    friend ostream &operator<<(ostream &os, const ModInt &a) { return os << a.x;}
    friend istream &operator>>(istream &is, ModInt &t){return is >> t.x;}

    ModInt pow(int64_t n) const {
        ModInt res(1), mul(x);
        while(n){
            if (n & 1) res *= mul;
            mul *= mul;
            n >>= 1;
        }
        return res;
    }
    
    ModInt inv() const {
        int a = x, b = mod, u = 1, v = 0;
        while (b) {
            int t = a / b;
            a -= t * b; swap(a, b);
            u -= t * v; swap(u, v);
        }
        if (u < 0) u += mod;
        return u;
    }
    
};
using mint = ModInt<mod>;

void solve(){
    int n,m;
    cin>>n>>m;

    vector<int> lim(n+1);
    vector<mint> f(n+1),pref(n+1);

    f[0]=1,pref[0]=f[0];
    
    while(m--){
        int l,r;
        cin>>l>>r;
        lim[r]=max(lim[r],l);
    }

    for(int i=1;i<=n;i++){
        lim[i]=max(lim[i],lim[i-1]);
    }

    for(int i=1;i<=n;i++){
        f[i]=pref[i-1];
        if(lim[i]>0){
            f[i]-=pref[lim[i]-1];
        }
        pref[i]=pref[i-1]+f[i];
    }

    cout<<f[n]*2<<endl;
}

signed main(){

	ios::sync_with_stdio(0);
	cin.tie(0);

	int t=1;
	cin>>t; 
	
	while(t--){
		solve(); 
	}

}

D. Almost Roman

posted @ 2025-12-01 17:21  LYET  阅读(8)  评论(0)    收藏  举报