联系衔接:blcakcat
HDU 4825
从最高为开始贪心,如何可以走当前位的异或结果就走异或结果否则就走当前结果
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
LL value[32 * qq];
int ch[32 * qq][2];
int n, m, node_cnt;
void Init() {
node_cnt = 1;
mst(ch[0], 0);
}
void Insert(LL x) {
int cur = 0;
for(int i = 32; i >= 0; --i) {
int idx = (x >> i) & 1;
if(!ch[cur][idx]) {
mst(ch[node_cnt], 0);
ch[cur][idx] = node_cnt;
value[node_cnt++] = 0;
}
cur = ch[cur][idx];
}
value[cur] = x;
}
LL Query(LL x) {
int cur = 0;
for(int i = 32; i >= 0; --i) {
int idx = (x >> i) & 1;
if(ch[cur][idx ^ 1]) cur = ch[cur][idx ^ 1];
else cur = ch[cur][idx];
}
return value[cur];
}
int main(){
int t; scanf("%d", &t);
int Cas = 0;
while(t--) {
Init();
scanf("%d%d", &n, &m);
for(int i = 0; i < n; ++i) {
LL x; scanf("%lld", &x);
Insert(x);
}
printf("Case #%d:\n", ++Cas);
for(int i = 0; i < m; ++i) {
LL x; scanf("%lld", &x);
printf("%lld\n", Query(x));
}
}
return 0;
}
HDU 5536
题意:给出n个求,求出(si + sj) ^ sk 的最大值,i,j,k互不相等
思路:先对所有数建一颗01字典树,然后枚举i,j,将si与sj从字典序中删除,贪心找最大的结果
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e3 + 10;
const int INF = 1e9 + 10;
int ch[32 * qq][2], value[32 * qq], node_cnt, n;
LL num[qq];
void Init() {
node_cnt = 1;
mst(ch[0], 0);
mst(value, 0);
}
void Insert(LL x) {
int cur = 0;
for(int i = 32; i >= 0; --i) {
int idx = (x >> i) & 1;
if(!ch[cur][idx]) {
mst(ch[node_cnt], 0);
ch[cur][idx] = node_cnt++;
}
cur = ch[cur][idx];
value[cur]++;
}
}
void Delete(LL x) {
int cur = 0;
for(int i = 32; i >= 0; --i) {
int idx = (x >> i) & 1;
cur = ch[cur][idx];
value[cur]--;
}
}
LL Query(LL x) {
int cur = 0;
LL ans = 0;
for(int i = 32; i >= 0; --i) {
int idx = (x >> i) & 1;
if(ch[cur][idx ^ 1] && value[ch[cur][idx ^ 1]]) {
ans |= (1LL << i);
cur = ch[cur][idx ^ 1];
} else {
cur = ch[cur][idx];
}
}
return ans;
}
int main(){
int t; scanf("%d", &t);
while(t--) {
Init();
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%lld", num + i);
Insert(num[i]);
}
LL maxn = 0;
for(int i = 1; i <= n; ++i) {
Delete(num[i]);
for(int j = i + 1; j <= n; ++j) {
LL x = num[i] + num[j];
Delete(num[j]);
maxn = max(maxn, Query(x));
Insert(num[j]);
}
Insert(num[i]);
}
printf("%lld\n", maxn);
}
return 0;
}
HDU 3460
题意:有n个字符串,你有一个打印机,你要使用打印机输出所有字符串,打印机有三种操作,增加一个字符,删除一个字符,打印,问最少需要操作多少次
思路:很明显可以建一颗字典树,但关键在于怎么求解,可以这样思考首先我们知道打印每个字符串的贡献是n,那么现在我们还需要计算打印的贡献和删除的贡献,我们建了一颗字典树,那么字典树上的所有节点都是需要打印的,这就是所有打印的贡献,删除的贡献呢?我们要明确最后肯定只剩下一个字符串,所以之前的肯定会被删除掉,所以我们假设全部删除,再加上一个最长字符串即删除操作的贡献
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e4 + 10;
const int INF = 1e9 + 10;
int ch[qq * 26][26];
int node_cnt, n;
char st[qq];
void Init() {
mst(ch[0], 0);
node_cnt = 1;
}
void Insert() {
int cur = 0;
int len = strlen(st);
for(int i = 0; i < len; ++i) {
int idx = st[i] - 'a';
if(!ch[cur][idx]) {
mst(ch[node_cnt], 0);
ch[cur][idx] = node_cnt++;;
}
cur = ch[cur][idx];
}
}
int main(){
while(scanf("%d", &n) != EOF) {
Init();
int maxn = 0;
for(int i = 0; i < n; ++i) {
scanf("%s", st);
maxn = max(maxn, (int)strlen(st));
Insert();
}
printf("%lld\n", -maxn + (node_cnt - 1) * 2LL + n);
}
return 0;
}