P3293 [SCOI2016] 美味
经典题,
考虑一个没有偏移量的时候如何计算,其实就是一个裸的可持久化
但是有了偏移量就不一样了,这会导致直接改变
套路的逐位考虑,从高位枚举到低位。假设当前找到的数为
由
code:
#include<bits/stdc++.h> #define int long long using namespace std; const int N = 2e5 + 10, M = 1e5; struct Persist_Seg{ #define mid (l + r >> 1) struct node{ int ls, rs, sum; }hjt[N << 5]; int root[N], cnt; void pushup(int o){hjt[o].sum = hjt[hjt[o].ls].sum + hjt[hjt[o].rs].sum;} void add(int l, int r, int pre, int& now, int x){ hjt[++cnt] = hjt[pre]; now = cnt; if(l == r){hjt[now].sum++; return;} if(x <= mid) add(l, mid, hjt[pre].ls, hjt[now].ls, x); else add(mid + 1, r, hjt[pre].rs, hjt[now].rs, x); pushup(now); } bool check(int l, int r, int Lo, int Ro, int s, int t){ if(l > r) return false; if(s <= l && r <= t) return hjt[Ro].sum - hjt[Lo].sum; bool ret = false; if(s <= mid) ret |= check(l, mid, hjt[Lo].ls, hjt[Ro].ls, s, t); if(mid < t) ret |= check(mid + 1, r, hjt[Lo].rs, hjt[Ro].rs, s, t); return ret; } }tr; int n, m; int solve(int pivot, int ad, int l, int r){ int ret = 0; for(int i = 20; i >= 0; i--){ int c = pivot & (1 << i); if(c && !tr.check(0, M, tr.root[l - 1], tr.root[r], ret - ad, ret - ad + (1 << i) - 1)) ret += (1 << i); else if(!c && tr.check(0, M, tr.root[l - 1], tr.root[r], ret - ad + (1 << i), ret - ad + (1 << i + 1) - 1)) ret += (1 << i); } return ret ^ pivot; } signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; for(int i = 1; i <= n; i++){ int x; cin >> x; tr.add(0, M, tr.root[i - 1], tr.root[i], x); } for(int i = 1; i <= m; i++){ int b, x, l, r; cin >> b >> x >> l >> r; cout << solve(b, x, l, r) << "\n"; } return 0; }
本文作者:Little_corn
本文链接:https://www.cnblogs.com/little-corn/p/18157527
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步