More than 2019 cattle off summer school camp (seventh) E + discrete segment tree

Topic Portal

The meaning of problems: given a number according to a certain formula $ <l, r> $, each coupled to a sequence of numbers l and r, and outputs the median.

Thinking: Each requires $ $ discretization interval, such as the $ [1,2] becomes $ $ [1,3) $, $ is [1,2) $ and $ [2,3) $, so in order to do a complete range of expression, or as [2,2] this section will be a problem.

  So we each of $ [l, r + 1) $ discrete, the number provided $ (x) $ x represents a discrete, each update time, the right interval should be $ (r + 1) -1 $ . For example, had only an interval $ [2,3] $, we expressed in $ [2,4) $, after discretization we update interval is $ [1,1] $, plus the number of digits is $ ve [ 2] -ve [1] $, ve is the original array.

  Query and update the same idea.

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
#define pb(a)  push_back(a)
#define rep(i,x,n) for(int i=x;i<=n;++i)
#define dep(i,n,x) for(int i=n;i>=x;--i)
using namespace std;
typedef long long ll;
int n,m;
const int inf=0x3f3f3f3f;
const int maxn=4e5+10;
ll x[maxn],y[maxn],A1,B1,C1,M1,A2,B2,C2,M2;
vector<ll >ve;
ll sz[maxn<<3],lazy[maxn<<3];
void add(int o,int l,int r,ll f){
    sz[o]+=(ve[r+1]-ve[l])*f;
    lazy[o]+=f;
}
void pushdown(int o,int l,int r){
    if(!lazy[o]||l==r)return;
    int mid=(l+r)>>1;
    add(o<<1,l,mid,lazy[o]);
    add(o<<1|1,mid+1,r,lazy[o]);
    lazy[o]=0;
}
void update(int o,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr){
        add(o,l,r,1);
        return;
    }
    int mid=(l+r)>>1;
    pushdown(o,l,r);
    if(ql<=mid)update(o<<1,l,mid,ql,qr);
    if(mid<qr)update(o<<1|1,mid+1,r,ql,qr);
    sz[o]=sz[o<<1]+sz[o<<1|1];
}

ll query(int o,int l,int r,int num){
    if(l==r){
        ll tot=sz[o]/(ve[l+1]-ve[l]);
        return ve[l]+(num-1)/tot;
    }
    pushdown(o,l,r);
    int mid=(l+r)>>1;
    if(sz[o<<1]>=num)return query(o<<1,l,mid,num);
    return query(o<<1|1,mid+1,r,num-sz[o<<1]);
}


int main(){
    int n;
    scanf("%d",&n);
    scanf("%lld%lld%lld%lld%lld%lld",&x[1],&x[2],&A1,&B1,&C1,&M1);
    scanf("%lld%lld%lld%lld%lld%lld",&y[1],&y[2],&A2,&B2,&C2,&M2);
       rep(i,3,n){
        x[i]=(A1*x[i-1]+B1*x[i-2]+C1)%M1;
        y[i]=(A2*y[i-1]+B2*y[i-2]+C2)%M2;
    }
    
    rep(i,1,n){
        x[i]++,y[i]++;
        if(x[i]>y[i]) swap(x[i],y[i]);
        ve.push_back(x[i]); ve.push_back(y[i]+1);
    }
    sort(ve.begin(),ve.end());
    ve.erase(unique(ve.begin(),ve.end()),ve.end());
    int cnt=ve.size();
    rep(i,1,n){
        
          x[i]=lower_bound(ve.begin(),ve.end(),x[i])-ve.begin();
        y[i]=lower_bound(ve.begin(),ve.end(),y[i]+1)-ve.begin();
        update(1,0,cnt,x[i],y[i]-1);
        printf("%lld\n",query(1,0,cnt,(sz[1]+1)/2));
    }
}

 

Guess you like

Origin www.cnblogs.com/mountaink/p/11327719.html