[SCOI 2016] 美味
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=4571
[算法]
二分 + 可持久化线段树逐位确定答案的每一位即可
时间复杂度 : O(NlogN^2)
[代码]
#include<bits/stdc++.h> using namespace std; const int N = 2e5 + 10; const int MAXLOG = 30; const int MAXP = N * MAXLOG; typedef long long ll; typedef long double ld; typedef unsigned long long ull; int n , m; int a[N] , rt[N]; struct Presitent_Segment_Tree { int sz; int latest[MAXP] , lc[MAXP] , rc[MAXP]; inline void init() { sz = 0; } inline void modify(int &now , int old , int l , int r , int x , int loc) { now = ++sz; lc[now] = lc[old] , rc[now] = rc[old]; latest[now] = loc; if (l == r) return; int mid = (l + r) >> 1; if (mid >= x) modify(lc[now] , lc[old] , l , mid , x , loc); else modify(rc[now] , rc[old] , mid + 1 , r , x , loc); } inline bool query(int now , int lft , int l , int r , int ql , int qr) { if (ql < 0) return false; if (ql > qr) return false; if (l == ql && r == qr) return latest[now] >= lft; int mid = (l + r) >> 1; if (mid >= qr) return query(lc[now] , lft , l , mid , ql , qr); else if (mid + 1 <= ql) return query(rc[now] , lft , mid + 1 , r , ql , qr); else return query(lc[now] , lft , l , mid , ql , mid) | query(rc[now] , lft , mid + 1 , r , mid + 1 , qr); } } PST; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } int main() { read(n); read(m); PST.init(); for (int i = 1; i <= n; i++) { read(a[i]); PST.modify(rt[i] , rt[i - 1] , 0 , 300000 , a[i] , i); } for (int i = 1; i <= m; i++) { int b , x , l , r , ans = 0; read(b); read(x); read(l); read(r); for (int j = 17; j >= 0; j--) { int now = ans + ((((b >> j) & 1) ^ 1) << j); if (PST.query(rt[r] , l , 0 , 300000 , max(0 , now - x) , now + (1 << j) - 1 - x)) ans = now; else ans = ans + (((b >> j) & 1) << j); } printf("%d\n" , ans ^ b); } return 0; }