AtCoder Beginner Contest 141

Posted CTing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 141相关的知识,希望对你有一定的参考价值。

AtCoder Beginner Contest 141

D - Powerful Discount Tickets

贪心 + 堆

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 1e5 + 5;
int a[N], n, m, f[N]; //f[i]:用了几张
ll ans;

int main () 
    cin >> n >> m;
    //用几张
    for (int i = 1; i <= n; i++)    cin >> a[i], ans += a[i];
    priority_queue<int> q;
    for (int i = 1; i <= n; i++) 
        int t = a[i];
        while (t > 0)   q.push (t - t / 2), t /= 2;
    

    while (!q.empty () && m --) 
        //cout << q.top () << endl;
        ans -= q.top ();
        q.pop ();
    
    cout << ans;



//dp

E - Who Says a Pun?

字符串中找到两个最长的一样的不重叠子串
最最最简单的dp

#include <bits/stdc++.h>
#define vi vector<int>

using namespace std;
const int N = 5e3 + 5;
int n, f[N][N], ans; //f[i][j]: i结尾与j结尾的匹配的最大长度
string s;

int main () 
    cin >> n >> s;
    s = \' \' + s;
    for (int i = 1; i <= n; i++) 
        for (int j = i + 1; j <= n; j++) 
            if (s[i] == s[j]) 
                if (i + f[i-1][j-1] < j)    f[i][j] = f[i-1][j-1] + 1;
                ans = max (ans, f[i][j]);
            
        
    
    cout << ans;



//dp

F - Xor Sum 3

不会写,没想到是线性基。
洛谷题解:https://www.luogu.com.cn/problem/solution/AT_abc141_f

啊啊又是位运算 1ll<< 这里!!太可恶了!!

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 1e5 + 5;
int a[N], cnt[63];
int n, ans;

struct linear_basis 
    int num[63];
    bool insert (int x) 
        for (int i = 60; i >= 0; i--) 
            if ((x >> i & 1) == 0)  continue;
            if (num[i] == 0) 
                num[i] = x;
                return true;
            
            else    x ^= num[i];
        
        return false;
    

    int query () 
        int x = 0;
        for (int i = 62; i >= 0; i --) 
            x = max (x, x ^ num[i]);
        
        return x;
    
T;

signed main () 
    cin >> n;
    for (int i = 1; i <= n; i++) 
        cin >> a[i];
        for (int j = 60; j >= 0; j--)    cnt[j] += (a[i] >> j & 1);   
    

    for (int j = 60; j >= 0; j--) 
        if (cnt[j] % 2 == 0)    continue; 
        ans += (1ll << j); //奇数贡献一直在
        for (int i = 1; i <= n; i++) 
            if (a[i] >> j & 1) 
                a[i] ^= (1ll << j);
            
        
    

    for (int i = 1; i <= n; i++)    T.insert (a[i]);
    cout << ans + 2 * T.query () << endl;



//划分成两部分,使得每部分的异或和最大
//恰好符合线性鸡定义
//找到最大ai
//按位考虑:当前位1次数为奇数->直接计入,偶数->x1^x2=0,x1取max,则x2取max

以上是关于AtCoder Beginner Contest 141的主要内容,如果未能解决你的问题,请参考以下文章