IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 2021“MINIEYE杯”中国大学生算法设计超级联赛(1)- 1006(Xor sum) -> 正文阅读

[开发测试]2021“MINIEYE杯”中国大学生算法设计超级联赛(1)- 1006(Xor sum)

补题链接:https://acm.hdu.edu.cn/showproblem.php?pid=6955

题目:

给定T组测试用例,对于每组测试用例有:
第一行输入两个数n, k
第二行输出n个数组成的序列[a1,a2…an]

求满足子序列的值异或和大于等于k的序列,满足条件的序列中长度最小的子序列,输出子序列的左右端点,如果存在多组满足条件的最小子序列,则输出左端点更小的

思路:

异或运算具有自反性,如果要求每个区间的异或值,我们可以利用前缀异或和的思想,即sum[i] 代表 a[1] ^ a[2] ^ a[3] ^....^ a[i]
[l, r]区间的异或和 = sum[r] ^ sum[l - 1]

我们可以将每一个sum[i]从高位到低位存储到01trie中,这样对于当前sum[i],前i - 1个sum值我们已经挂到01trie上,所以我们可以求得前i个序列中,满足sum[i] ^ sum[l] >= k 的离当前i 最近的l, 而为了求得最近的l,我们每插入一个sum值时,对于路径上的节点,都标记为当前i 值。

而对于查找 >= k 的异或值时,当异或值的最高的前 j> k 的前j位的值时,这条路径往下不管怎么走,总的异或值肯定 > k;而当异或值的最高的前 j< k 的前j位的值时,这条路径往下不管怎么走,总的异或值肯定 < k.

ACCode

#include<iostream>

using namespace std;
typedef long long ll;

// 32进制数
const int N = 32 * (1e5 + 10);

// cur, 当前值;
// sum[]: 异或前缀和
ll cur, sum[N], k;
// tree[]: 01trie;
// cnt[]: 最右出现的位置;
// idx: 当前新建节点(新节点的索引)
int tree[N][2], cnt[N], idx, t, n;

// 插入操作
void insert(int x, int pos){

    int p = 0;
    for (int i = 31; i >= 0; i--) {

        int t = x >> i & 1;
        if(!tree[p][t]){

            tree[p][t] = ++idx;
        }
        p = tree[p][t];
        // 记录t这个节点对应最大/右的点
        cnt[p] = max(cnt[p], pos);
    }
}

ll find(int x){
    // 当前节点
    int p = 0;
    // 最大异或值
    ll res = 0;
    // k的前i项值
    ll ck = 0;
    for (int i = 31; i >= 0; i--) {

        int t = x >> i & 1;
        int tk = k >> i & 1;

        ck = ck << 1 | tk;

        if(tree[p][!t]){
            res = res << 1 | 1;
            p = tree[p][!t];

        }else{
            res = res << 1;
            p = tree[p][t];
        }

        if(res < ck){
            return 0;
        }

        if(res > ck){
            return cnt[p] + 1;
        }
    }

    if(res >= ck) return cnt[p] + 1;

    return 0;
}

int main(){

    scanf("%d", &t);

    while(t--){

        scanf("%d%lld", &n, &k);

        ll len = n + 1;
        ll l = -1, r = -1;

        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &cur);

            if(len != 1 && cur >= k){
                l = i;
                r = i;
                len = 1;
            }

            sum[i] = cur ^ sum[i-1];
        }

        insert(0, 0);

        for (int i = 1; i <= n; ++i) {

            if(len == 1) break;

            insert(sum[i], i);

            ll cl = find(sum[i]);

            if(cl && (i - cl + 1) < len){
                len = (i - cl + 1);
                l = cl;
                r = l + len - 1;
            }
        }

        if(len != (n + 1)){
            printf("%lld %lld\n", l, r);
        }else{
            printf("-1\n");
        }

        for (int i = 0; i <= idx; ++i) {
            cnt[i] = 0;
            tree[i][0] = 0;
            tree[i][1] = 0;
        }
        idx = 0;
    }

    return 0;
}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 10:07:54  更:2021-08-06 10:09:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 10:11:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码