2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛(解题报告)

1001

签到。输出A&B,当(A&B == 0)时特判。

1002 HDU - 6703 array

因为给的数字是1-n的全排列,对于操作2,可以转换为查询区间[r+1,n]里面第一个大于等于k的数字。(考虑到该区间可能没有大于等于k的数字,可以在n+1位置插入数字n+1,就一定能查询到了。所以每次查询区间[r+1,n+1]第一个大于等于k的数字。)对于操作1,可以将加了1e7的数字放在一个set里面,无论查询的r给的是多少,答案都可以从set里面的数字更新。(即lower_bound找到第一个大于等于k的数字)

这样就只剩下一个问题了,如何查询区间第一个大于等于k的数字。可以考虑主席树。因为对于操作1只需要把更新的数字放入set所以就不需要更新主席树。每次操作2,如果k小于等于左子树最大值,则递归左子树。找到答案则直接return,否则递归右子树(这时候右子树的所有值都大于k)。
ps:这题用cin关同步居然没用,导致我一度怀疑模板有问题。
具体看代码:

#include <bits/stdc++.h>
using namespace std;

#define sz(a) a.size()
#define all(x) (x).begin(), (x).end()
#define foo(i, s, e) for(int i=(s);i<=(e);i++)
#define fod(i, s, e) for(int i=(e);i>=(s);i--)
#define endl '\n'
#define debug(a) cout<<#a<<": "<<a<<'\n'
#define mod(x) (((x)%MOD+MOD)%MOD)
#define mem(a) memset((a),0,sizeof(a))
typedef long long ll;
typedef unsigned long long ull;

const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 2e5 + 7;

int a[maxn], b[maxn], T[maxn];
int len = 0, tot;
struct node {
   
    int L, R;
    int sum;
} tree[maxn * 30];

int update(int root, int x, int l, int r) {
   
    int newroot = ++tot;
    tree[newroot] = tree[root]; tree[newroot].sum++;
    if(l == r) return newroot; int mid = (l + r) / 2;
    if(x <= mid) tree[newroot].L = update(tree[root].L, x, l, mid);
    else tree[newroot].R = update(tree[root].R, x, mid + 1, r);
    return newroot;
}

int sear(int left_root, int right_root, int l, int r, int k) {
   
    if(tree[right_root].sum == tree[left_root].sum) return INF;
    if(l == r) return l;
    int ans = INF; int mid = (l + r) / 2;

    if(k <= mid)
        ans = sear(tree[left_root].L, tree[right_root].L, l, mid, k);
    if(ans ==
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值