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>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 5e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

LL l, r, k;

void print(LL x, int cnt) {
    if(!cnt) return;
    print(x / 2, cnt - 1);
    printf("%d", x & 1);
}

int main() {
    scanf("%lld%lld%lld", &l, &r, &k);
    LL n = r - l + 1;
    if(k == 1) {
        printf("%lld\n", l);
        puts("1");
        printf("%lld\n", l);
    } else if(k == 2) {
        if(n == 2) {
            if(l < (l ^ r)) {
                printf("%lld\n", l);
                puts("1");
                printf("%lld\n", l);
            } else {
                printf("%lld\n", l ^ r);
                puts("2");
                printf("%lld %lld\n", l, r);
            }
        } else {
            if(l & 1) {
                printf("%lld\n", (l + 1) ^ (l + 2));
                puts("2");
                printf("%lld %lld\n", (l + 1), (l + 2));
            } else {
                printf("%lld\n", l ^ (l + 1));
                puts("2");
                printf("%lld %lld\n", l, (l + 1));
            }
        }
    } else if(k == 3) {
        LL t = 1;
        while(t * 2 <= l) t *= 2;
        if(t * 3 <= r) {
            puts("0");
            puts("3");
            printf("%lld %lld %lld\n", l, 3 * t, (3 * t) ^ l);
        } else {
            puts("1");
            puts("2");
            if(l & 1) printf("%lld %lld\n", l + 1, l + 2);
            else printf("%lld %lld\n", l, l + 1);
        }
    } else {
        if(l & 1) {
            if(n >= 5) {
                puts("0");
                puts("4");
                for(LL i = l + 1; i < l + 5; i++)
                    printf("%lld ", i);
                puts("");
            } else {
                for(int S = 1; S < (1 << n); S++) {
                    vector<LL> vc;
                    LL val = 0;
                    for(int i = 0; i < n; i++)
                        if(S >> i & 1) val ^= l + i, vc.push_back(l + i);
                    if(!val) {
                        puts("0");
                        printf("%d\n", SZ(vc));
                        for(auto& t : vc) printf("%lld ", t);
                        puts("");
                        return 0;
                    }
                }
                puts("1");
                puts("2");
                printf("%lld %lld\n", l + 1, l + 2);
            }
        } else {
            puts("0");
            puts("4");
            for(LL i = l; i < l + 4; i++)
                printf("%lld ", i);
            puts("");
        }
    }
    return 0;
}

/*
*/

原文地址:https://www.cnblogs.com/CJLHY/p/10467852.html

时间: 2025-01-22 12:31:47

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 --分类讨论+构造

题意:从区间[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,那

Codeforces 1041F Ray in the tube (看题解)

Ray in the tube 感觉是套路题.. 如果确定一个差值x我们如何取确定答案呢, 我们把a[ i ] -> a[ i ] % (2 * x), 把b[ i ] -> (b[ i ] + k) % (2 * x), 值相同的都能同时射到. 同时我们能发现, 对于一个差值x如果它有奇数因子, 把它除掉之后会更优, 所以我们要check的x只有2的幂次. #include<bits/stdc++.h> #define LL long long #define fi first

Codeforces 983E NN country 思维 (看题解)

NN country 是1175E的加强树上版本, 大致思路是一样的.. 难点在于判断两个点是否被同一条线覆盖.. 居然没想出来. 我们先把所有点对都离线,对于点对(u, v) 我们dfs到 u 的时候 记录一下v子树的和为 t1, 然后把所有在 u 的线段的另一端 + 1, 向子树递归, 回溯的时候再求一下 v 子树的和为 t2 只要判断t1 是否等于 t2, 就知道有没有一条线段同时覆盖u,v. #include<bits/stdc++.h> #define LL long long #d

Codeforces 750E New Year and Old Subsequence 线段树 + dp (看题解)

New Year and Old Subsequence 第一感觉是离线之后分治求dp, 但是感觉如果要把左边的dp值和右边的dp值合起来, 感觉很麻烦而且时间复杂度不怎么对.. 然后就gun取看题解了, 用线段树维护dp的值, 然后区间合并求答案. 每个节点保存dp[ i ][ j ]表示, 把当前管理的区间删到 s{2017}中的 s[ i + 1 ] - s[ j - 1 ],最少删几个, 然后合并的时候5 ^ 3合并. #include<bits/stdc++.h> #define L

Educational Codeforces Round 36 (Rated for Div. 2) 题解

Educational Codeforces Round 36 (Rated for Div. 2) 题目的质量很不错(不看题解做不出来,笑 Codeforces 920C 题意 给定一个\(1\)到\(n\)组成的数组,只可以交换某些相邻的位置,问是否可以将数组调整为升序的 解题思路 首先如果每个数都能通过交换到它应该到的位置,那么就可以调整为升序的. 但实际上交换是对称的,如果应该在的位置在当前位置前方的数都交换完成,那么整体就是排好序的,因为不可能所有不在相应位置的数都在相应位置的后方.

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 830C Bamboo Partition (看题解)

Bamboo Partition 列公式, 整除分块, 想不到, 好菜啊. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x)