C. Jon Snow and his Favourite Number DP + 注意数值大小

http://codeforces.com/contest/768/problem/C

这题的数值大小只有1000,那么可以联想到,用数值做数组的下标,就是类似于计数排序那样子。。

这样就可以枚举k次操作,然后for (int i = 0; i <= 1025; ++i),也就是O(1000 * k)的复杂度而已。

0--1000中任选两个数异或,最大值是1023

然后注意下只有奇数位异或,dp[now][val]计数转移下去就好了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 1e5 + 20;
int a[maxn];
vector<int>vc[maxn];
map<pair<int, int>, int>pos;
int dp[2][1025 + 20];
int f(int val) {
    return (val + 1) / 2;
}
void work() {
    int n, k, x;
    cin >> n >> k >> x;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        dp[0][a[i]]++;
    }
    int now = 0;
    for (int i = 1; i <= k; ++i) {
        now = !now;
        memset(dp[now], 0, sizeof dp[now]);
        int L = 1, R = 0;
        for (int j = 0; j <= 1025; ++j) {
            if (dp[!now][j]) {
                R = L + dp[!now][j] - 1;
                int has = f(R) - f(L - 1);
                dp[now][j ^ x] += has;
                dp[now][j] += dp[!now][j] - has;
                L = R + 1;
            }
        }
        assert(L == n + 1);
    }
    int mi = inf, mx = -inf;
    for (int i = 0; i <= 1025; ++i) {
        if (dp[now][i]) {
            mi = min(i, mi);
            mx = max(i, mx);
        }
    }
    cout << mx << " " << mi << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code

 

posted on 2017-02-21 21:13  stupid_one  阅读(186)  评论(0编辑  收藏  举报

导航