本題注意離散化的時候可能會出現區間串聯情況,比如
[1,10]? [5,10] [1,4] 和 [1,10] [6,10] [1,4] 直接離散化的話兩者一樣,但是實際上是不一樣的
解決辦法是你在相鄰的差不是1的數對中再插一個數就好了
離線區間染色 查詢根節點
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;const int N = 1e5+10,inf = 0x3f3f3f3f;
struct Segment{int l,r;int id;
}tr[N<<3];
bool st[N];
vector<int>v;
vector< pair<int,int> >op;
int m;
int findx(int x){return lower_bound(v.begin(),v.end(),x)-v.begin();}void pushdown(int u){if(tr[u].id){tr[u<<1].id = tr[u<<1|1].id = tr[u].id;tr[u].id = 0;}
}void build(int u,int l,int r){tr[u] = {l,r,0};if(l==r)return;int mid = l+r>>1;build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}void modify(int u,int l,int r,int c){if(tr[u].l>=l&&tr[u].r<=r){tr[u].id = c;return;}pushdown(u);int mid = tr[u].l+tr[u].r>>1;if(l<=mid)modify(u<<1,l,r,c);if(r>mid)modify(u<<1|1,l,r,c);}int query(int u){if(tr[u].id){if(st[tr[u].id])return 0;return st[tr[u].id] = 1;}if(tr[u].l==tr[u].r)return 0;return query(u<<1)+query(u<<1|1);
}int main()
{int _;cin>>_;while(_--){v.clear(),op.clear();v.push_back(-inf),op.push_back({0,0});memset(st,0,sizeof st);cin>>m;for(int i=1;i<=m;++i){int l,r;cin>>l>>r;v.push_back(l),v.push_back(r);op.push_back({l,r});}sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());int vlen = v.size();for(int i=1;i+1<vlen;++i)if(v[i+1]-v[i]>1)v.push_back(v[i+1]-1);sort(v.begin(),v.end());build(1,1,v.size()-1);for(int i=1;i<=m;i++){int l = findx(op[i].first),r =findx(op[i].second);modify(1,l,r,i);}cout<<query(1)<<"\n";}
}