Codeforces 460D Little Victor and Set --分类讨论+构造

题意:从区间[L,R]中选取不多于k个数,使这些数异或和尽量小,输出最小异或和以及选取的那些数。

解法:分类讨论。

设选取k个数。

1. k=4的时候如果区间长度>=4且L是偶数,那么可以构造四个数(L,L+1,L+2,L+3),这样的话(L^(L+1)) ^ ((L+2)^(L+3)) = 0,最优

如果L不是偶数,那么看从L+1到R有没有四个数,如果有则取该四个数,否则最小异或和达不到0,也达不到1了,不再考虑k=4,k=3时还有可能等于0,所以转到k=3

2. k=3时,要使异或和为0,那么要选取a,b,c,设a<b<c,三个数至少两位表示,且不能为0,所以我们这么构造:

11000...

10111...

01111...

因为 c 应尽量小,所以后面补0,那么下面两个后面全部补1.

我们枚举一个一个加位数,看是否有R>=c>a>=L,如果有,那么最小异或和为0,如果没有,那么异或和就最小是1了,如果有大于等于三个数的话,我们取两个数就能达到1(一定可以以偶数开头),所以此时取三个一定不比取两个更优,所以k=2就能解决,转k=2

3. k=2时,看有没有偶数开头的两个数(2x,2x+1),这时异或和为1,已经是当下最小的了,否则就只能比较L和L^R的大小再输出了。

4. k=1, 显然只能取一个数的时候,选的越小越好,选L

可以证明,k > 4的情况,一定可以通过取k<=4个达到异或和最小。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define lll __int64
using namespace std;
#define N 100107

int main()
{
    lll l,r;
    int k;
    while(scanf("%I64d%I64d%d",&l,&r,&k)!=EOF)
    {
        if(k >= 4) {              //0
            if(l%2 && r-l+1 >= 5) {
                printf("0\n4\n%I64d %I64d %I64d %I64d\n",l+1,l+2,l+3,l+4);
                continue;
            }
            else if(l%2 == 0 && r-l+1 >= 4) {
                printf("0\n4\n%I64d %I64d %I64d %I64d\n",l,l+1,l+2,l+3);
                continue;
            }
            k = 3;
        }
        if(k == 3) {                //0
            lll c = 3LL, b = 2LL, a = 1LL;
            int flag = 0;
            while(1) {
                if(c <= r && a >= l) { flag = 1; break; }
                if(c > r) break;
                a = a<<1|1;
                b = b<<1|1;
                c = c<<1;
            }
            if(flag) {
                printf("0\n3\n%I64d %I64d %I64d\n",a,b,c);
                continue;
            }
            k = 2;
        }
        if(k == 2) {                 //1
            int flag = 0;
            for(lll i=l;i<=l+1;i++) {
                if(i%2LL == 0 && i+1LL <= r) {
                    flag = 1;
                    printf("1\n2\n%I64d %I64d\n",i,i+1LL);
                }
            }
            if(!flag) {
                if((l^r) < l)  printf("%I64d\n2\n%I64d %I64d\n",l^r,l,r);
                else         printf("%I64d\n1\n%I64d\n",l,l);
            }
        }
        if(k == 1) {                      //unkown
            printf("%I64d\n1\n%I64d\n",l,l);
            continue;
        }
    }
    return 0;
}

时间: 2024-12-29 12:30:02

Codeforces 460D Little Victor and Set --分类讨论+构造的相关文章

Codeforces 460D Little Victor and Set(构造)

题目链接:Codeforces 460D Little Victor and Set 题目大意:给定范围l,r,选小于k个数,使得这些数的亦或和最小. 解题思路:加入k为偶数,那么kXOR(k+1)=1 根据这个可以处理掉k≠3的所有情况. 对于k=3的情况,找到一个大于l的2k,如果满足2k+1≤r,那么就可以构造出三个数亦或值为0的情况. #include <cstdio> #include <cstring> #include <algorithm> using

codeforces 460D Little Victor and Set(构造、枚举)

最近的CF几乎都没打,感觉挺水的一个题,不过自己仿佛状态不在,看题解才知道做法. 输入l, r, k (1 ≤ l ≤ r ≤ 1012; 1 ≤ k ≤ min(106, r - l + 1)). 从[l,r]选至多k个数使得选出的数的异或值最小,输出最小异或值和方案. 分类讨论,首先如果r-l+1<=4,枚举集合解决之. 先面讨论r-l+1>=5的情况: 此时有至少5个数可以选择,故至少有连续的4个数满足2x,2x+1,2x+2,2x+3. k==1时显然方案为{l}.k==2时,显然方案

Codeforces 460D Little Victor and Set(看题解)

Little Victor and Set 其他都很好求, 只有k == 3的时候很难受.. 我们找到第一个不大于l的 t, 答案为 l, 3 * t, (3 * t) ^ l 感觉好像是对的, 感觉又不会证明, 啊, 我好菜啊. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #

codeforces 460D:Little Victor and Set

Description Little Victor adores the sets theory. Let us remind you that a set is a group of numbers where all numbers are pairwise distinct. Today Victor wants to find a set of integers S that has the following properties: for all x the following in

Codeforces 506D Mr. Kitayuta&#39;s Colorful Graph 并查集+水水的分类讨论+水水的离线预处理

首先读入所有的边与询问.将边按颜色分类. 按颜色进行并查集, 若此并查集内的点<= 100,则100*100/2的枚举是否联通. 若此并查集内的点  > 100,则将与这些点相关的所有询问查一遍. 那么时间复杂度为100*100/2*(M/100),或者为M/100*Q. 极限的时候两种方法都在一亿左右了,而且每次还需要在map里搞一搞,还要查询是否联通,不知道为啥没有超时.. #include <algorithm> #include <iostream> #incl

【推导】【分类讨论】Codeforces Round #431 (Div. 1) B. Rooter&#39;s Song

给你一个这样的图,那些点是舞者,他们每个人会在原地待ti时间之后,以每秒1m的速度向前移动,到边界以后停止.只不过有时候会碰撞,碰撞之后的转向是这样哒: 让你输出每个人的停止位置坐标. ①将x轴上初始坐标记为(pi,0),y轴上的初始坐标记为(0,pi).只有pi-ti相同的才有可能发生碰撞.于是可以按照这一点将人划分为很多组,不同组之间绝对不会互相影响. ②假设一组内每个人都不会发生碰撞,那么所有的路线交叉点都是碰撞点.所以碰撞次数可能达到n^2次,暴力不可行. ③对于一组内,形成了一个网格图

【树链剖分】【dfs序】【LCA】【分类讨论】Codeforces Round #425 (Div. 2) D. Misha, Grisha and Underground

一棵树,q次询问,每次给你三个点a b c,让你把它们选做s f t,问你把s到f +1后,询问f到t的和,然后可能的最大值是多少. 最无脑的想法是链剖线段树--但是会TLE. LCT一样无脑,但是少一个log,可以过. 正解是分类讨论, 如果t不在lca(s,f)的子树内,答案是dis(lca(s,f),f). 如果t在lca(s,f)的子树内,并且dep(lca(s,t))>dep(lca(f,t)),答案是dis(lca(s,t),f): 否则答案是dis(lca(f,t),f). #in

dp+分类讨论 Gym 101128E

题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/details/61428924 Description n个小木条,一段前面有一个小箭头,给出第一个小木条的非箭头端端点横坐标以及每个小木条箭头端的坐标,现在要从下往上把这n'个木条按顺序叠放好,要求相邻两个小木条必须有一个共同端点且有交叠部分,问小木条有多少种放法 Input 第一行一整数n表示木条数量,之

cf 251 B Playing with Permutations 暴力 分类讨论

题链;http://codeforces.com/problemset/problem/251/B B. Playing with Permutations time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Little Petya likes permutations a lot. Recently his mom has p