ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #816 (Div. 2) A-C

2022-08-24 18:32:06  阅读:126  来源: 互联网

标签:相等 cout int cin Codeforces solve Div 贡献 816


C题想了一种线段树,然后统计所有左右端点的麻烦做法,

 

A 题:思维

将长的边作为横坐标,短的边作为纵坐标,从左走到右即可。

注意当一条边横跨中间的那条线之后,另一条边只用多走一步就可以到达另一条路

//-------------------------代码----------------------------

//#define int ll
const int N = 1e5+10;
int n,m;

void solve()
{
    cin>>n>>m;
    if(n > m)  swap(n,m);
    if(m == 1 ) {
    cout<<0<<endl;rt;}
    cout<< (n - 1) * 2 + 1 + (m - 1) <<endl;
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

B题 模拟+构造

题意:n个数,每个数,除k向下取整并累加的和 等于 b ,和等于 s

构造这 n 个数

这n 个数的和最小 等于 k * b 

最大等于 k * (b + 1) - 1

然后保持 s 为后 n - i 个数的和 挨个输出就可以了

 

//-------------------------代码----------------------------

#define int ll
const int N = 1e5+10;
int n,m,k,b,s;

void solve()
{
    cin>>n>>k>>b>>s;
    int mx = max(1ll * 0,k * (b+1) - 1);
    int mn = k * b;
    if(mx + (n-1) * (k-1) < s || mn > s) {
//        dbb(mx + (n-1) * (k-1),s)
//        dbb(mn,s);
        cout<<-1<<endl;
        rt; 
    }
    int cnt = n;
    if(mx >= s) {
        cout<<s<<' '; n -- ;
        while(n -- ) cout<<0<<' ';
    } else {
        cout<<mx<<' ';
        s -= mx;
        cnt -- ;
        while(s) {
            cnt -- ;
            if(s > k - 1) {
                cout<<k - 1<<' ';s -= k - 1;
            } else {
                cout<<s<<' ';s -= s;
            }
        }
        while(cnt) {
            cout<<0<<' ';
            cnt -- ;
        }
    }
    cout<<endl;
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

C题:思维 贡献题   关键:维护连续相等的数的第一个点的贡献

求所有左边界和右边界,对于每个l 和 r 它的不同的数的种类的总和

对每个位置的数,计算它的贡献

枚举到 i ,左边界可以是[1,i] 右边界可以是 [i,n]

一:如果当前数 和左边不相等,贡献就是 i * (n - i + 1)

二:如果当前数 和左边相等,分几种情况

1. 将右边界定为 i

第一种 左边界 在连续相等的数之外,这个时候 这个数就没有贡献

第二种 左边界 在连续相等的 数之内,那它们的 位置到这个位置 都只有左边第一个数的贡献,后面的数包括这个数没有贡献

第三种 左边界 是 i ,因为是第一个数,所以有贡献。

2. 右边界定为 [i+1,n]

如果前面有相等 的数,左边界只有等于 i 的时候这个数才有一个贡献,

如果没有相等的数,就是第一种情况 

考虑右边有相等的数,因为这个数是第一个数,所以有一个贡献。

最后推出来 贡献是 (n - i + 1)

所以总共的贡献是 i * (n - i + 1) - (i - 1) * (n - i + 1) 

[1,i],[i,n] - [1,i-1],[i,n] = [i],[i,n] 

 

题目要求 维护单点修改后 的总贡献

考虑左右两边。

对于左边,如果改之前是连续相等,或者不相等,改之后也是一样,那相当于没改

  一:如果改之前是连续相等,改之后不相等,这个点 原来的贡献是 [i],[i,n] 现在是[1,i],[i,n] 

这个点的贡献就要加上 [1,i-1],[i,n] 的贡献,也就是 + (i-1) * (n-i+1) 

  二:如果改之前不想当,改之后相等,这个点 原来的贡献是 [1,i],[i,n] 现在是 [i],[i,n] 

这个点的贡献要减去 [1,i-1],[i,n] 的贡献, 就是 - (i-1)*(n-i+1) 

//-------------------------代码----------------------------

#define int ll
const int N = 1e5+10;
int n,m,k,b,s;

void solve()
{
    cin>>n>>k>>b>>s;
    int mx = max(1ll * 0,k * (b+1) - 1);
    int mn = k * b;
    if(mx + (n-1) * (k-1) < s || mn > s) {
//        dbb(mx + (n-1) * (k-1),s)
//        dbb(mn,s);
        cout<<-1<<endl;
        rt; 
    }
    int cnt = n;
    if(mx >= s) {
        cout<<s<<' '; n -- ;
        while(n -- ) cout<<0<<' ';
    } else {
        cout<<mx<<' ';
        s -= mx;
        cnt -- ;
        while(s) {
            cnt -- ;
            if(s > k - 1) {
                cout<<k - 1<<' ';s -= k - 1;
            } else {
                cout<<s<<' ';s -= s;
            }
        }
        while(cnt) {
            cout<<0<<' ';
            cnt -- ;
        }
    }
    cout<<endl;
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

标签:相等,cout,int,cin,Codeforces,solve,Div,贡献,816
来源: https://www.cnblogs.com/er007/p/16621177.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有