ICode9

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

Codeforces Round #321 (Div. 2)

2019-10-14 21:52:27  阅读:302  来源: 互联网

标签:return int d% Codeforces mid seg 321 query Div


A. Kefa and First Steps

求最长递增连续子序列。

 

B. Kefa and Company

排序二分就行了。

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 1e5 + 7;

struct P {
    ll m, s;
    P(ll m = 0, ll s = 0): m(m), s(s) {}
    bool operator < (const P &rhs) const {
        return m < rhs.m;
    }
} p[N];

ll sum[N];

int main() {
    int n;
    ll d;
    scanf("%d%lld", &n, &d);
    for (int i = 1; i <= n; i++)
        scanf("%lld%lld", &p[i].m, &p[i].s);
    sort(p + 1, p + n + 1);
    ll ans = 0;
    for (int i = 1; i <= n; i++) 
        sum[i] = sum[i - 1] + p[i].s;
    for (int i = 1; i <= n; i++) {
        int pos = upper_bound(p + i + 1, p + n + 1, P(d + p[i].m - 1, 0)) - p;
        pos--;
        if (pos < i) continue;
        ans = max(ans, sum[pos] - sum[i - 1]);
    }
    printf("%lld\n", ans);
    return 0;
}
View Code

 

C. Kefa and Park

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 7;
vector<int> G[N];
int n, m, ans;
int havecat[N];

void dfs(int u, int fa, int con) {
    if (G[u].size() == 1) {
        if (con <= m) ans++;
        return;
    }
    for (auto v: G[u]) {
        if (v == fa) continue;
        if (!havecat[v]) dfs(v, u, 0);
        else if (con + 1 <= m) dfs(v, u, con + 1);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) 
        scanf("%d", &havecat[i]);
    for (int i = 1, u, v; i < n; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    G[1].push_back(0);
    dfs(1, 0, havecat[1]);
    printf("%d\n", ans);
}
View Code

 

D. Kefa and Dishes

显然状压,因为吃了一些菜品之后,只跟最后一个吃的是哪一个有关,即一个集合只跟最后一个加入的元素有关。
$dp[s][i]$ 表示吃了集合 $s$ 的菜品,最后一个吃的是第 $i$ 个菜品。
转移 $dp[s | (1 << j)] = dp[s] + a[j] + c[i][j]$
吃了 $m$ 个菜品就在转移过程中计算就行了。
复杂度 $O(n^2 2^n)$

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 18;
const int sz = (1 << N) + 1;

ll mp[N][N], dp[sz][N], a[N];

inline int getone(int s) {
    int cnt = 0;
    while (s) {
        cnt++;
        s &= (s - 1);
    }
    return cnt;
}

template<class T>
inline void checkmax(T &a, T b) {
    if (a < b) a = b;
}

int main() {
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    memset(dp, -1, sizeof(dp));
    for (int i = 0; i < n; i++) 
        scanf("%lld", &a[i]), dp[1 << i][i] = a[i];
    for (int i = 0; i < k; i++) {
        int u, v; ll c;
        scanf("%d%d%lld", &u, &v, &c);
        u--, v--;
        mp[u][v] = c;
    }
    int S = 1 << n;
    ll ans = 0;
    for (int s = 1; s < S; s++)
        for (int i = 0; i < n; i++) if ((s >> i & 1) && dp[s][i] >= 0) {
            if (getone(s) == m) checkmax(ans, dp[s][i]);
            for (int j = 0; j < n; j++) if (!(s >> j & 1)) 
                checkmax(dp[s | (1 << j)][j], dp[s][i] + a[j] + mp[i][j]);
        }
    printf("%lld\n", ans);
    return 0;
}
View Code

 

E. Kefa and Watch

题意:
给一个数字串。操作一为区间修改。操作二询问一个区间是否周期为 $d$

思路:
判断周期可以用哈希。
相当于有 $|s| - d$ 个等式。
$s[l] = s[l + d]$
$s[l + 1] = s[l + d + 1]$
$\dots$
$s[r - d] = s[r]$
把左边和右边分别拼起来就是判 $[l, r - d]$ 和 $[l + d, r]$ 相同
那么线段树维护哈希值即可。
刚开始用自然溢出,两个seed咋改都没用。
然后用了两个模数才行。

#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;

const int N = 1e5 + 7;
int n, m, k;
char s[N];

struct Seg {
    #define lp p << 1
    #define rp p << 1 | 1
    ull tree[N * 4], bit[N], sum[N], seed, MOD;
    int lazy[N * 4];
    inline void init() {
        for (int i = bit[0] = sum[0] = 1; i < N; i++) {
            bit[i] = (bit[i - 1] * seed) % MOD;
            sum[i] = (sum[i - 1] + bit[i]) % MOD;
        }
        build(1, 1, n);
    }
    inline void pushup(int p, int llen, int rlen) {
        tree[p] = (tree[lp] * bit[rlen] % MOD + tree[rp]) % MOD;
    }
    inline void tag(int p, int dig, int len) {
        lazy[p] = dig;
        tree[p] = sum[len - 1] * dig % MOD;
    }
    inline void pushdown(int p, int llen, int rlen) {
        if (lazy[p] >= 0) {
            tag(lp, lazy[p], llen);
            tag(rp, lazy[p], rlen);
            lazy[p] = -1;
        }
    }
    void build(int p, int l, int r) {
        lazy[p] = -1;
        if (l == r) {
            tree[p] = s[l] - '0';
            return;
        }
        int mid = l + r >> 1;
        build(lp, l, mid);
        build(rp, mid + 1, r);
        pushup(p, mid - l + 1, r - mid);
    }
    void update(int p, int l, int r, int x, int y, int dig) {
        if (x <= l && y >= r) {
            lazy[p] = dig;
            tree[p] = dig * sum[r - l] % MOD;
            return;
        }
        int mid = l + r >> 1;
        pushdown(p, mid - l + 1, r - mid);
        if (x <= mid) update(lp, l, mid, x, y, dig);
        if (y > mid) update(rp, mid + 1, r, x, y, dig);
        pushup(p, mid - l + 1, r - mid);
    }
    ull query(int p, int l, int r, int x, int y) {
        if (x > y) return 0;
        if (x <= l && y >= r) return tree[p];
        int mid = l + r >> 1;
        pushdown(p, mid - l + 1, r - mid);
        if (y <= mid) return query(lp, l, mid, x, y);
        if (x > mid) return query(rp, mid + 1, r, x, y);
        return (query(lp, l, mid, x, y) * bit[min(y, r) - (mid + 1) + 1] % MOD + query(rp, mid + 1, r, x, y)) % MOD;
    }
} seg[2];

int main() {
    scanf("%d%d%d", &n, &m, &k);
    m += k;
    scanf("%s", s + 1);
    seg[0].seed = 233; seg[0].MOD = 201326611;
    seg[1].seed = 2333; seg[1].MOD = 402653189;
    seg[0].init(); seg[1].init();
    for (int opt, l, r, d; m--; ) {
        scanf("%d%d%d%d", &opt, &l, &r, &d);
        if (opt == 1) {
            for (int i = 0; i < 2; i++)
                seg[i].update(1, 1, n, l, r, d);
        } else {
            if (r - l + 1 == d || (seg[0].query(1, 1, n, l, r - d) == seg[0].query(1, 1, n, l + d, r) && seg[1].query(1, 1, n, l, r - d) == seg[1].query(1, 1, n, l + d, r))) {
                puts("YES");
            } else {
                puts("NO");
            }
        }
    }
    return 0;
}
View Code

 

标签:return,int,d%,Codeforces,mid,seg,321,query,Div
来源: https://www.cnblogs.com/Mrzdtz220/p/11674387.html

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

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

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

ICode9版权所有