额 set+线段树+st倍增
我好菜啊
这个是三元组,很明显set维护
但是要找到从l开始最远更新值
线段树维护区间最大值
然后建立ST表
倍增快速找到答案
#include<bits/stdc++.h>
#include<set>
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
const int N=2e5+100;
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
int n,m,k;
struct Node{
int l,r,q;
}A[N];
bool operator < (Node A,Node B){
return (A.l<B.l)||(A.l==B.l&&A.r<B.r);
}
struct Segment_Tree{
struct Data{
int l,r,sum;
int lazy;
}T[N<<2];
void PushDown(int p){
if(T[p].lazy){
T[lc].sum=max(T[p].lazy,T[lc].sum);
T[rc].sum=max(T[p].lazy,T[rc].sum);
T[lc].lazy=max(T[p].lazy,T[lc].lazy);
T[rc].lazy=max(T[p].lazy,T[rc].lazy);
T[p].lazy=0;
}
}
void Build(int p,int l,int r){
T[p].l=l;
T[p].r=r;
if(l==r){
T[p].sum=-1;
return;
}
int mid=(l+r)>>1;
Build(lc,l,mid);
Build(rc,mid+1,r);
}
void Update(int p,int l,int r,int val){
if(l<=T[p].l&&T[p].r<=r){
T[p].sum=max(T[p].sum,val);
T[p].lazy=max(T[p].lazy,val);
return;
}
PushDown(p);
int mid=(T[p].l+T[p].r)>>1;
if(l<=mid)Update(lc,l,r,val);
if(mid< r)Update(rc,l,r,val);
}
int Query(int p,int pos){
if(T[p].l==pos&&T[p].r==pos){
return T[p].sum;
}
PushDown(p);
int mid=(T[p].l+T[p].r)>>1;
if(pos<=mid)return Query(lc,pos);
else return Query(rc,pos);
}
}Tree;
set<Node> S[N];
int st[N][21];
int Find(int l,int r){
int ans=0;
for(int i=20;i>=0;i--){
if(st[l][i]<r&&st[l][i]){
ans+=(1<<i);
l=st[l][i];
}
}
if(st[l][0]>=r)return ans+1;
else return -1;
}
int main(){
// freopen("test.in","r",stdin);
// freopen("test.out","w",stdout);
read(n);
read(m);
read(k);
Tree.Build(1,1,n);
for(int i=1;i<=m;++i){
read(A[i].l);
read(A[i].r);
read(A[i].q);
S[A[i].q].insert(A[i]);
}
for(int i=1;i<=k;++i){
set<Node> :: iterator It=S[i].begin();
int last=1;
for(;It!=S[i].end();++It){
Node tmp=*It;
int l=tmp.l;
// if(last==2)cout<<"IN"<<" "<<last<<" "<<l<<' '<<i<<'\n';
if(l>last)Tree.Update(1,last,l,l);
last=max(last,tmp.r);
}
Tree.Update(1,last,n,n);
}
for(int i=1;i<=n;++i){
st[i][0]=Tree.Query(1,i);
// cout<<i<<" "<<st[i][0]<<'\n';
}
for(int j=1;j<=20;++j){
for(int i=1;i<=n;++i){
if(i+(1<<j)-1<=n){
st[i][j]=st[st[i][j-1]][j-1];
}
}
}
int q;
read(q);
for(int i=1;i<=q;++i){
int l,r;
read(l);
read(r);
cout<<Find(l,r)<<'\n';
}
}