Codeforces Round #367 (Div. 2)

来源:互联网 发布:json rpc 2.0 php 编辑:程序博客网 时间:2024/05/12 00:20

A

B
题意:给定n个数和q次查询,每次查询给定一个整数m,问你<=m的数有多少个。
二分即可。

C
题意:给定n个串,将第i个串翻转的代价是a[i],问你是否存在一种方案使得这n个串按字典序排列,存在则输出最小代价,反之输出-1。

水dp
dp[i][0]表示前i个串满足字典序排列且第i个串不翻转
dp[i][1]表示前i个串满足字典序排列且第i个串翻转

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <string>#define ll o<<1#define rr o<<1|1using namespace std;typedef long long LL;typedef pair<string, int> pii;const int MAXN = 1e5 + 10;const int INF = 1e9 + 10;pii a[MAXN];LL dp[MAXN][2];string b[MAXN];int main(){    int n;    while(cin >> n) {        for(int i = 0; i < n; i++) {            cin >> a[i].second;        }        for(int i = 0; i < n; i++) {            cin >> a[i].first;            b[i] = a[i].first;            reverse(b[i].begin(), b[i].end());        }        bool flag = true;        for(int i = 0; i < n; i++) {            if(i == 0) {                dp[i][0] = 0;                dp[i][1] = a[i].second;            }            else {                dp[i][0] = dp[i][1] = 1e15;                if(a[i].first >= a[i-1].first) {                    dp[i][0] = dp[i-1][0];                }                if(a[i].first >= b[i-1]) {                    dp[i][0] = min(dp[i][0], dp[i-1][1]);                }                if(b[i] >= a[i-1].first) {                    dp[i][1] = dp[i-1][0] + a[i].second;                }                if(b[i] >= b[i-1]) {                    dp[i][1] = min(dp[i][1], dp[i-1][1] + a[i].second);                }            }            if(dp[i][0] == dp[i][1] && dp[i][0] == 1e15) {                flag = false; break;            }        }        if(flag) {            printf("%lld\n", min(dp[n-1][0], dp[n-1][1]));        }        else {            printf("-1\n");        }    }    return 0;}

D

题意:初始多重集合里面有一个0,现在有q次操作。分三种
一、+ v把整数v放入多重集合;
二、- v 把整数从多重集合去掉;
三、? v查询x Xor v的最大值 其中x属于多重集合元素。

字典树水题,不能再裸了。

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <string>#define ll o<<1#define rr o<<1|1using namespace std;typedef long long LL;typedef pair<string, int> pii;const int MAXN = 6e6 + 10;const int INF = 1e9 + 10;int f[31];int Next[MAXN][2], word[MAXN], L, root;int newnode() {    for(int i = 0; i <= 1; i++) {        Next[L][i] = -1;    }    word[L++] = 0;    return L - 1;}void init() { L = 0; root = newnode(); }void Insert(int val) {    int u = root; int v;    for(int i = 30; i >= 0; i--) {        if(val & f[i]) {            v = 1;        }        else {            v = 0;        }        if(Next[u][v] == -1) {            Next[u][v] = newnode();        }        u = Next[u][v];        word[u]++;    }}void Delete(int val) {    int u = root; int v;    for(int i = 30; i >= 0; i--) {        if(val & f[i]) {            v = 1;        }        else {            v = 0;        }        u = Next[u][v];        word[u]--;    }}int Query(int val) {    int ans = val;    int u = root; int v;    for(int i = 30; i >= 0; i--) {        if(val & f[i]) {            v = 1;        }        else {            v = 0;        }        if(v == 1) {            if(Next[u][0] != -1 && word[Next[u][0]]) {                u = Next[u][0];            }            else {                u = Next[u][1]; ans ^= f[i];            }        }        else {            if(Next[u][1] != -1 && word[Next[u][1]]) {                u = Next[u][1]; ans ^= f[i];            }            else {                u = Next[u][0];            }        }    }    return ans;}int main(){    f[0] = 1;    for(int i = 1; i <= 30; i++) {        f[i] = f[i-1] * 2;    }    int q;    while(scanf("%d", &q) != EOF) {        init(); Insert(0);        while(q--) {            char op[10]; int v;            scanf("%s%d", op, &v);            if(op[0] == '+') {                Insert(v);            }            else if(op[0] == '-') {                Delete(v);            }            else {                printf("%d\n", Query(v));            }        }    }    return 0;}
0 0