1. 程式人生 > >可持久化線段樹(cf1080F)

可持久化線段樹(cf1080F)

 

大佬部落格 https://www.cnblogs.com/zinthos/p/3899565.html

 

題目:https://codeforces.com/problemset/problem/1080/F

題目大意:

  給你k個線段,每個線段屬於一個集合(n),每次查詢a,b,x,y,求[a,b]的集合是否都存在一個區間[l,r]使得l<=x&&r>=y

解法:

  題目等同於,對於[a,b]中的每一個集合,左端點大於x的線段中最小的右端點,的最大值是否<=y;

  對線段排序(根據左端點l值),根據線段左端點值l由大到小依次插入更新線段樹(插入時維護最小值),線段樹維護[1,n]上的最大的區間右端點值(所有的 集合的最小右端點 的最大值),每次更新需要複製的節點數最多為log個,端點數最多為nlogn

 

#include<bits/stdc++.h>
using namespace std;
#define freread freopen("input.txt","r",stdin);
#define frewrite freopen("output.txt","w",stdout);
typedef long long ll;
const int maxn=3e5+7;
const int inf=(1LL<<31)-1;
int n,m,k,ar[maxn];
struct node{
    int l,r,mx;
}no[
6000001]; struct data{ int l,r,v; operator < (const data& other){ return l<other.l; } void prin(){ cout<<"da = "<<l<<" "<<r<<" "<<v<<endl; } }da[maxn]; int root[maxn],tot=0; void newNode(int& u,int p){ u=++tot; no[u]
=no[p]; } void push(int x){ no[x].mx=max(no[no[x].l].mx , no[no[x].r].mx); } void build(int l,int r,int &o){ newNode(o,0); if(l==r){ no[o].mx=inf; return ; } int mid=l+r>>1; build(l,mid,no[o].l); build(mid+1,r,no[o].r); push(o); } void ensert(int l,int r,int& o,int pre,int a,int b){ newNode(o,pre); if(l==r){ no[o].mx=min(no[o].mx, b); return ; } int mid=l+r>>1; if(a<=mid)ensert(l,mid,no[o].l,no[o].l,a,b); else ensert(mid+1,r,no[o].r,no[o].r,a,b); push(o); } int que(int l,int r,int o,int a,int b){ if(l==a && r==b){ return no[o].mx; } int mid=l+r>>1; int ans=0; if(a<=mid)ans=max(ans, que(l,mid,no[o].l,a,min(b,mid))); if(b>mid)ans=max(ans, que(mid+1,r,no[o].r,max(a,mid+1),b)); return ans; } int findpos(int x){ int l=1,r=k+1; while(l<r){ int mid=(l+r)>>1; if(da[mid].l>=x)r=mid; else l=mid+1; } return l; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;i++){ scanf("%d%d%d",&da[i].l,&da[i].r,&da[i].v); } sort(da+1,da+k+1); build(1,n,root[k+1]); for(int i=k;i>=1;i--){ ensert(1,n,root[i],root[i+1],da[i].v,da[i].r); } da[k+1].l=1e9+1; while(m--){ int a,b,x,y; scanf("%d%d%d%d",&a,&b,&x,&y); int ans=que(1,n,root[findpos(x)],a,b); puts(ans<=y? "yes":"no"); fflush(stdout); } return 0; }
View Code