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的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242