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|1
using 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;
}
题意:初始多重集合里面有一个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|1
using 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;
}