HDU 6703 array(主席树)
题意
给定一个长度为n的排列(1-n),要你实现操作两种,
1 x:给第x个数加上1e7;
2 x y:查询最小的且不小于y的且不在区间[1,x]里出现过的数。
题解
对权值建主席树,维护区间最小值,插入一个数相当于这个数被ban,进行1操作相当于取消ban,如果真去实现修改会比较麻烦,由于这个序列是一个排列,我们对一些数取消ban相当于答案可以直接出现在这些数里,所以我们可以用set保存一下取消ban的数然后联合查询即可。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<stack> #include<cstdlib> #include<queue> #include<set> #include<string.h> #include<vector> #include<deque> #include<map> using namespace std; #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define eps 1e-4 #define bug printf("*********\n") #define debug(x) cout<<#x"=["<<x<<"]" <<endl #define Mod(a,b) a<b?a:a%b+b typedef long long LL; typedef long long ll; const int maxn = 1e5 + 5; #define ls lson #define rs rson #define up update #define qu query int a[maxn],root[maxn],minv[maxn * 20],lson[maxn * 20],rson[maxn * 20]; int cnt,tot; void build(int &o, int l, int r) { o = ++tot; if (l == r) { minv[o] = l; return; } int mid = (l + r) >> 1; build(lson[o], l, mid); build(rson[o], mid + 1, r); minv[o] = min(minv[lson[o]], minv[rson[o]]); } void update(int &o, int pre, int l, int r, int p) { o = ++cnt; lson[o] = lson[pre]; rson[o] = rson[pre]; if (l == r) { minv[o] = 1e9; return; } int mid = (l + r) >> 1; if (p <= mid) update(lson[o], lson[pre], l, mid, p); else update(rson[o], rson[pre], mid + 1, r, p); minv[o] = min(minv[lson[o]],minv[rson[o]]); } int query(int o, int l, int r, int ql, int qr){ if(l >= ql && r <= qr) return minv[o]; int mid = (l + r) >> 1; int res = 1e9; if(ql <= mid) res = min(res,query(lson[o], l, mid, ql, qr)); if(qr > mid) res = min(res,query(rson[o],mid + 1, r, ql, qr)); return res; } set<int>s; int h = 1e5 + 1; int main() { int T; scanf("%d", &T); build(root[0], 1, h); while (T--) { cnt = tot; s.clear(); int n, q; scanf("%d %d", &n, &q); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); update(root[i], root[i - 1], 1, h, a[i]); } int lastans = 0; int id, x, y; while (q--) { scanf("%d", &id); if (id == 1) { scanf("%d", &x); x ^= lastans; s.insert(a[x]); } else { scanf("%d %d", &x, &y); x ^= lastans; y ^= lastans; int res1 = query(root[x], 1, h, y, h); int res2 = 1e9; auto it = s.lower_bound(y); if(it != s.end()) res2 = *it; lastans = min(res1,res2); printf("%d\n",lastans); } } } }

浙公网安备 33010602011771号