QOJ 17177. Wonderful Interval 2 题解
题目链接。
因为这道题学了 ODT 。
先将条件转化一下,不难发现为 \(L \le i \le R\),满足 \([a_i,b_i] \in [b_l,\dots,b_r]\)。
由于 \(b_i\) 肯定在 \([b_l \dots b_r]\) 中,因此可以转化为两个集合比大小。
令集合 \(S\) 为所有 \([a_i,b_i]\) 的交集,\(T\) 为 \([b_l,\dots,b_r]\) 的交集。那么就是当 \(|S| = |T|\) 时,结果为真。
考虑使用 ds 进行维护。尝试对 \(r\) 进行扫描线,刻画一下结果的变化。\(|T|\) 的修改是简单的,用 BIT 维护区间出现数的种类就行。主要是 \(|S|\) 的问题。
考虑使用 BIT + ODT 进行 \(|S|\) 的维护,表示区间内的 \(|S|\) 的大小。ODT 负责区间推平,把位置推到 \(r\) 上,BIT 则是负责记录。做完了。
Code
实现感觉细节很多。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define File(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define LL long long
#define fi first
#define se second
#define IT set<node>::iterator
const int N = 250000 + 10;
const int M = 1000000 + 10;
int a[N],b[N];
int lst[M];
vector< pair<int,int> > ques[N];
int lsh[M];
int n;
int tot;
int ans[N];
struct sgt{
int tre[N];
int lowbit(int x){return x & (-x);}
void update(int x,int k){if(x == 0) return ;while(x <= n){tre[x] += k;x += lowbit(x);}}
int query(int x){if(x == 0) return 0;int sum = 0;while(x){sum += tre[x];x -= lowbit(x);}return sum;}
int query(int l,int r){return query(r) - query(l-1);}
}BIT[2];
struct ODT{
struct node{
int l,r;
LL v;
node(int L,int R=-1,int v=0): l(L),r(R),v(v) {}
bool operator < (const node& o) const{return l < o.l;}
};
set<node> st;
IT split(int pos){
IT it = st.lower_bound(node(pos));
if(it != st.end() && it->l == pos) return it;
if(it == st.begin()) return st.end();
it -- ;
int L,R;L = it->l;R = it->r ;LL val = it->v;
if(pos < L || pos >= R) return st.end();
st.erase(it);
st.insert(node(L,pos,val));
return st.insert(node(pos,R,val)).first;
}
void assign(int l,int r,int pos){
IT itr = split(r);
IT itl = split(l);
if(!(itl == st.end() || itr == st.end())){
for(;itl!=itr;itl++){
BIT[0].update(itl->v,-(itl->r - itl->l));
}
itl = split(l);
st.erase(itl,itr);
}
st.insert(node(l,r,pos));
BIT[0].update(pos,r-l);
return ;
}
}odt;
vector<int> array_operation(vector<int> A, vector<int> B, vector<int> L,vector<int> R){
vector<int> Ans;
n = A.size();
for(int i=1;i<=n;i++){
a[i] = A[i-1] + 1;
lsh[++tot] = a[i];
}
for(int i=1;i<=n;i++){
b[i] = B[i-1] + 1;
lsh[++tot] = b[i];
}
sort(lsh+1,lsh+1+tot);
int len = unique(lsh+1,lsh+1+tot) - lsh - 1;
for(int i=1;i<len;i++){
if(lsh[i] != lsh[i+1] - 1) lsh[++tot] = lsh[i]+1;
}
sort(lsh+1,lsh+1+tot);
tot = unique(lsh+1,lsh+1+tot) - lsh - 1;
for(int i=1;i<=n;i++){
a[i] = lower_bound(lsh+1,lsh+1+tot,a[i]) - lsh;
b[i] = lower_bound(lsh+1,lsh+1+tot,b[i]) - lsh;
}
odt.st.insert(ODT::node(1,tot+2,0));
int Q = L.size();
for(int i=0;i<Q;i++){ques[R[i]+1].push_back({L[i]+1,i+1});}
for(int r=1;r<=n;r++){
odt.assign(a[r],b[r]+1,r);
if(lst[b[r]]){BIT[1].update(lst[b[r]],-1);}
BIT[1].update(r,1);
lst[b[r]] = r;
for(auto [l,id] : ques[r]){
if(BIT[0].query(l,r) == BIT[1].query(l,r)) ans[id] = 1;
}
}
for(int i=1;i<=Q;i++)
Ans.push_back(ans[i]);
return Ans;
}

浙公网安备 33010602011771号