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
原文地址:https://www.cnblogs.com/keam37/p/4430202.html