Codeforces Round #299 (Div. 1)

Problem A:

实际上对于一段数字假设和为k,每次取较大的m个进行t次减一操作,最多减去的是min(m*t,k).

明白了这个结论就可以直接二分答案了。

#include <bits/stdc++.h>

#define LL long long

using namespace std;

LL A, B, n;

LL l, t, m, ans;

int main() {

    ios::sync_with_stdio (0);

    cin >> A >> B >> n;

    for (int i = 1; i <= n; i++) {

        cin >> l >> t >> m;

        LL a = A + (l - 1) * B;

        int el = l, er = l + t, last = -1;

        while (el <= er) {

            int mid = (el + er) >> 1;

            LL b = A + (mid - 1) * B;

            if ( (a + b) * (mid - l + 1) / 2 <= t * m && b <= t && t >= a) last = mid, el = mid + 1;

            else

                er = mid - 1;

        }

        cout << last << endl;

    }

}
536A

 

Problem B:

对于匹配串p,的位置xi和xj 只要判断是否有冲突,没有的冲突的话,统计确定的位置的数量k,答案就是26^(n-k).否则答案就是0.

判断冲突利用KMP的next数组就行了.

#include <bits/stdc++.h>

#define LL long long

using namespace std;

const int MAXN = 1000009;

const int MOD = int (1e9 + 7);

int n, m;

int p[MAXN];

char s[MAXN];

int main() {

    ios::sync_with_stdio (0);

    cin >>  n >> m >> (s + 1);

    int len = strlen (s + 1);

    for (int i = 2, j = 0; i <= len; i++) {

        if (j && s[j + 1] != s[i]) j = p[j];

        if (s[j + 1] == s[i]) j++;

        p[i] = j;

    }

    int k = 0;

    for (int i = 1, x, y = 0; i <= m; i++) {

        cin >> x;

        if (y && y + len > x) {

            int tem = len;

            while (p[tem] > y + len - x)

                tem = p[tem];

            if (p[tem] != y + len - x) {

                cout << 0 << endl;

                return 0;

            }

            else k -= y - x;

        }

        else if (y && y + len <= x) k += len;

        y = x;

    }

    if(m) k += len;

    LL ans = 1, tem = 26;

    k = n - k;

    while (k) {

        if (k & 1) ans = (ans * tem) % MOD;

        tem = (tem * tem) % MOD;

        k >>= 1;

    }

    cout << ans << endl;

}
536B

 

你可能感兴趣的:(codeforces)