Codeforces Round #553 (Div. 2) AB DE(思维专场)

A:Maxim and Biology

B:Dima and a Bad XOR

D:Stas and the Queue at the Buffet

E:Number of Components

 

 

A

给一个字符串  问你可以最少多少次操作可以让里面出现一个“ACTG”。操作就是字符+1或者-1。‘Z'+1='A'反之同理

直接每隔4个跑一下,然后取个min就好了

B(上场就被B关了,这场还是被B关了,1个小时才过,噗。。。)

假设都取第一列,那么除去第i行的那个数,剩下的异或起来一定是一个定值,只要保证不等于这个定值就好了,所以直接找一行不相同的,check一下就好了。注意行全部相同的时候

2 3

1 1 1 

2 2 2

(我卡在这儿好久。。。)

代码写丑了。。。。

ll a[600][600];
ll f[600][600];
    int t,m;
map<int,int>mp;
void solve(vector<int> v,int k)
{
    for(auto d:v){
        ll s = 0;
        for(int i = 1;i <= n;i++){
            if(i == k) continue;
            s ^= a[i][1];
        }
        s ^= d;
        if(s > 0){
            int id = 0;
            for(int i = 1;i <= m;i++){
                if(d == a[k][i]){
                    id = i;
                    break;
                }
            }
            for(int i = 1;i <= n;i++){
                if(i != k) cout << 1 <<  " ";
                else cout << id << " ";
            }
            return ;
        }
    }
    return ;
}
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n >> m){
            set<int>s[600];
        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= m;j++){
                cin >> a[i][j];
                s[i].insert(a[i][j]);
            }
        }

        for(int i = 1;i <= n;i++){
            if(s[i].size() >= 2){
                    cout << "TAK" << endl;
                    vector<int>v;
                    for(auto d:s[i]) v.push_back(d);
                    solve(v,i);
                    return 0;
            }
        }
        ll ss = 0;
        for(int i = 1;i <= n;i++){
            ss ^= a[i][1];
        }
        if(ss > 0){
                    cout << "TAK" << endl;
            for(int i = 1;i <= n;i++){
                cout <<1 <<" ";
            }
            cout << endl;
            return 0;
        }
        cout << "NIE" << endl;
    }
    cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

C 不会 还没看,,,

给你ai和bi,求这个式子1到n求和,考虑贡献,如果a和b向后移动一位,那么贡献就会增加a-b,所以直接按这个贡献排序然后计算就可以了。

bool cmp(P a,P b){
    return a.fi - a.se > b.fi - b.se;
}

按这个排序一下就好了

E 非常巧妙的一个题,给你一条链,每个点上有权值,f(l,r),代表权值l到r的点上,有多少个联通块,最后求和,问有多少个

在这儿要知道森林的一个性质,就是联通块数 = 总点数 - 总边数

那我们考虑x~y这两个点的贡献,就是a[x] ~ a[y],然后当l<= a[x] && r >= a[y]的时候这两点做贡献,所以就很容易可以得出来

i * (n + 1 - i) 

再看边的贡献 也是一样,注意比较一下大小。

ll c[maxn];
ll a[maxn];
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n){
        for(ll i = 1;i <= n;i++)cin >> a[i],c[a[i]]++;
        ll ans = 0;
        for(ll i = 1;i <= n;i++){
            ans += c[i] * i * (n - i + 1);
        }
        for(ll i = 1; i < n;i++){
            ll x = a[i],y = a[i + 1];
            if(x > y) swap(x,y);
            ans -= x * (n - y + 1);
        }
        cout<< ans << endl;
    }
    cerr << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值