hdu6703 array(线段树)

题目链接
大意:给你一个1-n的排列,然后支持两种操作

  1. l ,给x这个位置加上1e7
  2. l r,询问1-r位置上没出现过且大于等于r的最小值
    思路:我们建一颗权值线段树,维护区间元素的最大位置;
    首先答案肯定在1-n+1中,所以对于修改操作来说 直接单点修改成一个极大的值。
    询问操作我们直接询问r-n+1的元素出现在>l位置中的最小元素即可。
    因为是最小值所以我们在递归的过程中,先搜小的,搜到就直接返回即可,不然会超时。
    细节见代码
#include<bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define LL long long
#define SZ(X) X.size()
#define pii pair<int,int>
#define ALL(X) X.begin(),X.end()

using namespace std;

LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
LL lcm(LL a, LL b) {return a / gcd(a, b) * b;}
LL powmod(LL a, LL b, LL MOD) {LL ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
const int N = 2e5 + 11;
int T, n, m;
int t[N << 2], Q[N << 2];
int a[N], b[N];
#define ls o<<1
#define rs o<<1|1
#define mid (l+r>>1)
//查询k+1-n+1 第一个>r的x
void build(int o, int l, int r) {
    if (l == r) {
        t[o] = b[l];
        return ;
    }
    build(ls, l, mid);
    build(rs, mid + 1, r);
    t[o] = max(t[ls], t[rs]);
}
void u(int o, int l, int r, int k, int d) {
    if (l == r) {
        t[o] = d;
        return ;
    }
    if (k <= mid)u(ls, l, mid, k, d);
    else u(rs, mid + 1, r, k, d);
    t[o] = max(t[ls], t[rs]);
}
int get(int o, int l, int r, int x, int y, int k) {
    if (x <= l && y >= r) {
        if (l == r) {
            return l;
        }
    }
    int ans = n + 2;
    if (x <= mid && t[ls] > k) {
        ans = min(ans, get(ls, l, mid, x, y, k));
    }
    if (y > mid && t[rs] > k && ans == n + 2) {
        ans = min(ans, get(rs, mid + 1, r, x, y, k));
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    // freopen("1.in", "r", stdin);
    for (cin >> T; T; T--) {
        cin >> n >> m;
        for (int i = 1; i <= n; i++)cin >> a[i], b[a[i]] = i;
        a[n + 1] = n + 1;
        b[n + 1] = n + 1;
        n++;
        build(1, 1, n);
        int last = 0;
        for (int i = 1; i <= m; i++) {
            int o, l, r;
            cin >> o;
            if (o == 1) {
                cin >> l;
                l ^= last;
                u(1, 1, n, a[l], 1e9);
            } else {
                cin >> l >> r;
                l ^= last;
                r ^= last;
                last = get(1, 1, n, r , n + 1, l);
                cout << last << '\n';
            }
        }
    }
    return 0;
}
全部评论

相关推荐

真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务