K - LOVER II UVALive - 8522 thinking line tree

Posted by adsegzy on Wed, 30 Oct 2019 22:42:50 +0100

Title Link: https://vj.ti12z.cn/33213da9be509cd5008cd64ae75e75bd?v=1562346904

 

Title:

Let's give you a n array of a with N length and an array of b with m length. When the sum of a[i] and b[i] is greater than or equal to k, I and j can match. Now let's give you several queries, each time I ask you an interval [l,r], and ask if the number of positions from l to r in the array of b can match all the corresponding positions of array a.

Practice:

The meaning of the problem is simple. The data is very explicit, which tells us that it is a problem of data structure. It also thinks that to find the r that satisfies the condition at the leftmost end of each l before preprocessing, it is similar to the idea of scale taking, but it just doesn't think of how to do it.

Some optimizations are necessary, such as first processing out every k-a[i]=a'[i] and then sorting out how many are greater than in b.

Teammates put forward the idea that a large number of b can be used to fill in a'[i] that is less than or equal to it. Later, I looked at people's code and learned a very interesting processing method (after all, I still can't cook my own dishes). I assigned the sorted a'[i] according to the subscript line tree, such as the number 4 5 6 7 - 4-3-2-1, which is recorded in the line tree. Record the minimum value. As long as Minn [1] > 0, then all the numbers meet the conditions. Why? Every time we add a number b[j], we get pos less than or equal to this number. We will add one to the interval [1,pos], which means that this number can be used to fill in all the values less than or equal to this number. When Minn [1] > 0, all the numbers are legal, so we can take it again.

It's a wonderful question.

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i =(int) a;i <=(int)b;i++)
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long ll;
const int maxn=200005;
int a[maxn],b[maxn],R[maxn];
int lef[maxn<<2],laz[maxn<<2];
int n,m,k,q;
void build(int l,int r,int rt){
    laz[rt]=0;
    if(l==r){
        lef[rt]=-(n-l+1);
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,lson);
    build(mid+1,r,rson);
    lef[rt]=min(lef[lson],lef[rson]);
}
void deal(int rt,int v){
    laz[rt]+=v;
    lef[rt]+=v;
}
void push_down(int rt){
    if(laz[rt]){
        deal(lson,laz[rt]);
        deal(rson,laz[rt]);
        laz[rt]=0;
    }
}
void add(int l,int r,int ql,int qr,int rt){
    if(ql<=l&&r<=qr){
        deal(rt,1);
        return ;
    }
    push_down(rt);
    int mid=(l+r)/2;
    if(ql<=mid) add(l,mid,ql,qr,lson);
    if(qr>mid) add(mid+1,r,ql,qr,rson);
    lef[rt]=min(lef[lson],lef[rson]);
}
void sub(int l,int r,int ql,int qr,int rt){
    if(ql<=l&&r<=qr){
        deal(rt,-1);
        return ;
    }
    push_down(rt);
    int mid=(l+r)/2;
    if(ql<=mid) sub(l,mid,ql,qr,lson);
    if(qr>mid) sub(mid+1,r,ql,qr,rson);
    lef[rt]=min(lef[lson],lef[rson]);
}

int main() {
    int T;
    cin>>T;
    while(T--){
        scanf("%d%d%d",&n,&m,&k);
        rep(i,1,n) scanf("%d",&a[i]),a[i]=k-a[i],R[i]=maxn;
        rep(i,1,m) scanf("%d",&b[i]);
        sort(a+1,a+1+n);
        build(1,n,1);
        int rr=0;
        for(int i=1;i<=m;i++){
            while(lef[1]<0&&rr<=m){
                rr++;
                if(rr<=m){
                    int pos=upper_bound(a+1,a+1+n,b[rr])-a-1;
                    if(pos>=1) add(1,n,1,pos,1);
                }
            }
            R[i]=rr;
            int lpos=upper_bound(a+1,a+1+n,b[i])-a-1;
            if(lpos>=1)sub(1,n,1,lpos,1);
        }
        scanf("%d",&q);
        while(q--){
            int l,r;
            scanf("%d%d",&l,&r);
            if(R[l]<=r) printf("1\n");
            else printf("0\n");

        }
    }
    return 0;
}

 

Topics: less