[Codeforces 979D] Kuro and GCD and XOR and SUM

题目链接: http://codeforces.com/problemset/problem/979/D

题目大意: 先有一个空的数组a, 有n个操作, 维护两种操作。 1操作, 向a数组加入一个数u。 2操作, 在a数组找到一个数v, 满足k | GCD(x, v), v + x <= s, 且v XOR x最大, 输出这个v, 不存在则输出-1。(所有的数组都 <= 10^5)。

思路: 考虑比较暴力的方法。 先建立10^5个trie树, 第i个trie树只考虑数组中能被i整除的a, 每个节点存的是当前子树存在的数的最小值。 预处理10^5范围内每个数的因数, 可以用数倍数的方式, O(nlogn)的复杂度预处理出来。 这样对于一个新加的数, 就是往每个它的因数所对应的trie数中插入它, 查找也就在对应的trie树中和一般的找最大异或值的方法类似。 总的复杂度是O(n(logn)^2)级别的。

#include <vector>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = (int)1e5 + 10;
const int M = 20;

int n;
vector<int > d[N]; bool has[N];

int cnt, rt[N], ch[N * 200][2], mn[N * 200];

int newNode(){
    ++ cnt;
    ch[cnt][0] = ch[cnt][1] = 0;
    mn[cnt] = N;
    return cnt;
}

void init(){
    for (int i = 1; i < N; i ++)
        for (int j = 0; j < N; j += i)
            d[j].push_back(i);

    mn[0] = N;
    for (int i = 1; i < N; i ++)
        rt[i] = newNode();
}

void insert(int u, int v, int k){
    mn[u] = min(mn[u], v);

    if (k == -1) return;

    int t = (v & (1 << k)) ? 1 : 0;

    if (!ch[u][t]){
        ch[u][t] = newNode();
    }

    insert(ch[u][t], v, k - 1);
}

int find(int u, int v, int m, int k){

    if (k == -1) return 0;

    int t = (v & (1 << k)) ? 1 : 0;

    if (mn[ch[u][!t]] <= m){
        return find(ch[u][!t], v, m, k - 1) | ((!t) << k);
    }
    else if (mn[ch[u][t]] <= m){
        return find(ch[u][t], v, m, k - 1) | (t << k); 
    }
    else return -1;
}

int main(){
    init();

    scanf("%d", &n);
    for (int i = 1; i <= n; i ++){
        int opt, u, k, s, x;
        scanf("%d", &opt);
        if (opt == 1){
            scanf("%d", &u);
            if (has[u]) continue;
            has[u] = true;

            for (int j = 0; j < d[u].size(); j ++)
                insert(rt[d[u][j]], u, M);
        }
        else{
            scanf("%d %d %d", &x, &k, &s);

            if (x % k != 0){
                printf("-1\n");
                continue;
            }

            printf("%d\n", find(rt[k], x, s - x, M));
        }
    }


    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值