您的位置:首页 > 其它

CF 470 div2 B - D 题解.

2018-03-12 19:09 411 查看
传送门

B:

题意: 两个人轮流玩游戏, 首先有一个x0 >= 3, 然后A先手,第 i 轮每个人选择一个小于X(i-1)的素数然后算出这个素数的倍数并且离x(i-1)最近的那个数作为xi, 现在给定x2,问最小的x0是多少.

思路: 首先我们可以通过算出x2的素因子得出x1的范围, 因为要范围尽量的大, 也就是包含的情况尽量的多, 那么肯定选择最大素因子, 对于一个数N, 最大素因子为P(N), 那么它的前一个数只能是[N - P(N) + 1, N], 所以我们得到了X1的范围, 然后遍历X1的所有情况重复如此可以得出x0的范围, 我们取所有x0的情况的最小值….这样直接算的复杂度为N√N, 比较慢, 所以我们先O(nlogn)预处理出所有1e6以内的数的最大素因子, 所以复杂度就降为了nlogn + n.

AC Code

const int maxn = 1e6+5;
int f[maxn];
bool ispri[maxn];
void init() {
Fill(ispri, true);
ispri[0] = ispri[1] = false;
for (int i = 2 ; i <= 1000000 ; i ++) {
if (ispri[i]) {
f[i] = i;
for (int j = i*2 ; j <= 1000000 ; j += i) {
ispri[j] = false;
f[j] = i;
}
}
}
}
void solve()
{
init();
int n;
while(~scanf("%d", &n)) {
int l = n - f
+ 1;
int ans = inf;
for (int i = l ; i <= n ; i ++) {
if (i - f[i] + 1 >= 3)
ans = min(i-f[i]+1, ans);
}
printf("%d\n", ans);
}
}


C: 有n天,第一行给出每天出现的雪球的体积, 第二行给出每天的温度, 问每天融化掉的雪球的体积.

思路: 首先我们做一个温度前缀和, 然后对于每i天的雪球体积算出它在第k天刚好化完, 那么第i天到第k-1天这个雪球作出的贡献就是这几天的温度, 所以我们用一个数组记录一下a[i]++, a[k]–, 然后单独算出第k天融化的体积, 最后扫一遍通过前缀的方法, 就可算出每天的融化的雪球体积了. 具体细节请看代码…..

AC Code

const int maxn = 1e5+5;
ll V[maxn], T[maxn], sum[maxn];
int b[maxn];
ll ans[maxn];
void solve()
{
int n;
while(~scanf("%d", &n)) {
Fill(b, 0);
for (int i = 1 ; i <= n ; i ++) {
scanf("%d", V + i);
}
for (int i = 1 ; i <= n ; i ++) {
scanf("%d", T + i);
sum[i] = T[i] + sum[i-1];
}
for (int i = 1 ; i <= n ; i ++) {
int k = lower_bound(sum+i, sum+1+n, V[i] + sum[i-1]) - sum;
b[i]++, b[k]--;
ans[k] += V[i] - (sum[k-1] - sum[i-1]);
}
ll res = 0;
for (int i = 1 ; i <= n ; i ++) {
res += b[i];
ans[i] += res*T[i];
}
for (int i = 1 ; i <= n ; i ++) {
printf("%lld%c", ans[i], i == n?'\n':' ');
}
}
}


D: 有n个数, 输出n个数, 第i个数表示第二行的第i个数与第三行中的某个数异或的最小值, 输出这n个数最小字典序的情况.

思路: 这个就是01字典树的裸题啊, 要最小那么在01字典树上就尽量走相同的点即可啊, 然后记得算出一个删除一个即可, 随便套套板子就行乐.

AC Code

const int maxn = 5e6+5;
const int siz = 33;
int cas=1;
int n, m;
struct Trie
{
int num, val, nex[2];
}trie[maxn];
int idx, a[maxn];
void build(int n) {
bitset<siz>bit(n);
int x = 0;
for(int i = 31 ; i >= 0 ; i --) {
int k = bit[i];
if(!trie[x].nex[k])
trie[x].nex[k] = ++idx;
x = trie[x].nex[k];
trie[x].num++;
}
trie[x].val = n;
}
int query(int n) {
bitset<siz>bit(n);
int x = 0;
for(int i = 31 ; i >= 0 ; i --) {
int k = bit[i];
if(trie[trie[x].nex[k]].num)
x = trie[x].nex[k ];
else x = trie[x].nex[k^1];
}
return trie[x].val;
}
void del(int n) {
bitset<siz>bit(n);
int x = 0;
for(int i = 31 ; i >= 0 ; i--) {
int k = bit[i];
x = trie[x].nex[k];
trie[x].num--;
}
}
void solve() {
idx = 0; Fill(trie, 0);
scanf("%d", &n);
for (int i = 1 ; i <= n ; i ++) {
scanf("%d", a + i);
}
for (int i = 1 ; i <= n ; i ++) {
int u; scanf("%d", &u);
build(u);
}
for (int i = 1 ; i <= n ; i ++) {
int tmp = query(a[i]);
printf("%d%c", tmp^a[i], i == n?'\n':' ');
del(tmp);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: