Find the median (range segment tree discrete + update)

Topic links: https://ac.nowcoder.com/acm/contest/887/E

Links: https://ac.nowcoder.com/acm/contest/887/E
Source: Cattle-off network

Find the median
Time limit: C / C ++ 3 seconds to 6 seconds languages other
space restrictions: C / C ++ 131072K, other languages 262144K
64bit IO the Format:% LLD

Title Description

Let median of some array be the number which would stand in the middle of this array if it was sorted beforehand. If the array has even length let median be smallest of of two middle elements. For example, median of the array [10,3,2,3,2] is 3 (i.e. [2,2,3‾,3,10][2,2,\underline{3},3,10][2,2,3,3,10]). Median of the array [1,5,8,1] is 1 (i.e. [1,1‾,5,8][1,\underline{1},5,8][1,1,5,8]).

At first, you're given an empty sequence. There are N operations. The i-th operation contains two integers LiL_iLi and RiR_iRi. This means that adding Ri−Li+1R_i-L_i+1RiLi+1 integers Li,Li+1,...,RiL_i, L_i+1, ... , R_iLi,Li+1,...,Ri into the sequence. After each operation, you need to find the median of the sequence.

Enter a description:

The first line of the input contains an integer N (1≤N≤400000)N\ (1 \leq N \leq 400000)N (1N400000) as described above.

The next two lines each contains six integers in the following format, respectively:

- X1 X2 A1 B1 C1 M1X_1\ X_2\ A_1\ B_1\ C_1\ M_1X1 X2 A1 B1 C1 M1
- Y1 Y2 A2 B2 C2 M2Y_1\ Y_2\ A_2\ B_2\ C_2\ M_2Y1 Y2 A2 B2 C2 M2

These values are used to generate Li,RiL_i, R_iLi,Ri as follows:

We define:
- Xi=(A1×Xi−1+B1×Xi−2+C1) module M1X_i = (A_1 \times X_{i-1} + B_1 \times X_{i-2} + C_1)\ module\ M_1Xi=(A1×Xi1+B1×Xi2+C1) module M1, for i=3 to Ni = 3\ to\ Ni=3 to N
- Yi=(A2×Yi−1+B2×Yi−2+C2) module M2Y_i = (A_2 \times Y_{i-1} + B_2 \times Y_{i-2} + C_2)\ module\ M_2Yi=(A2×Yi1+B2×Yi2+C2) module M2, for i=3 to Ni = 3\ to\ Ni=Li=min(Xi,Yi)+1L_i = min(X_i, Y_i) + 1i=1 to Ni = 1\ to\ NRi=max(Xi,Yi)+1R_i = max(X_i, Y_i) + 1i=1 to Ni = 1\ to\ N1≤N≤4000001 \leq N \leq 4000000≤A1<M10 \leq A_1 < M_10≤A2<M20 \leq A_2 < M_20≤B1<M10 \leq B_1 < M_10≤B2<M20 \leq B_2 < M_20≤C1<M10 \leq C_1 < M_10≤C2<M20 \leq C_2 < M_20≤X1<M10 \leq X_1 < M_10≤X2<M10 \leq X_2 < M_10≤Y1<M20 \leq Y_1 < M_20≤Y2<M20 \leq Y_2 < M_21≤M1≤1091 \leq M_1 \leq 10^91≤M2≤1091 \leq M_2 \leq 10^93toNWe also define:- Li=min(Xi,Yi)+1,for ot1=in  



  N.-
Ri=max(Xi,Yi)+1, for i=1 to N.Limits:


1N400000
0A1<M1
0A2<M2
0B1<M1
0B2<M2
0C1<M1
0C2<M2
0X1<M1
0X2<M1
0Y1<M2
0Y2<M2
1M1109
1M2109

Output Description:

You should output 
lines. Each line contains an integer means the median.
Example 1

Entry

copy
5
3 1 4 1 5 9
2 7 1 8 2 9

Export

copy
3
4
5
4
5

Explanation

= L [. 3, 2,. 4,. 1,. 7] 

R = [. 4,. 8,. 8,. 3,. 9]
subject to the effect: The meaning of the questions can be obtained by an array of length L and R interval N of each to all the numbers are added to the collection of the number of L [i] -R [i] between, every time you ask to join the median after what, the number of output this
idea: first of all discrete L and R but discrete here not R [i] but R [i] +1 very specific reason, I do not know, but after the interval when requested to do so, and only need R [i] -L [i], do not need R [i] -L [i] +1
look at the code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
const int maxn=400000+5;
LL x[maxn],y[maxn],l[maxn],r[maxn];
LL lazy[maxn<<3],sz[maxn<<3];
vector<LL>ve;
int cnt;
void deal(int rt,int l,int r,LL f)
{
    sz[rt]+=(ve[r+1]-ve[l])*f;lazy[rt]+=f;//注意这里要r+1
}
void Update(int l,int r,int rt,int L,int R)
{
//    cout<<"l:"<<l<<" r:"<<r<<endl;
    if(L<=l&&r<=R)
    {
        deal(rt,l,r,1);
        return ;
    }
    int mid=(l+r)>>1;
    if(lazy[rt])
    {
        deal(rt<<1,l,mid,lazy[rt]);
        deal(rt<< 1|1,mid+1,r,lazy[rt]);
        lazy[rt]=0;
    }
    if(L<=mid) Update(l,mid,rt<<1,L,R);
    if(R>mid) Update(mid+1,r,rt<<1|1,L,R);
    sz[rt]=sz[rt<<1]+sz[rt<<1|1];
}
LL Query(int l,int r,int rt,LL x)
{
//    cout<<"ql:"<<l<<" qr:"<<r<<" x:"<<x<<endl;
    if(l==r)
    {
        intSZ = Ti [RT] / (VE [L + . 1 ] -ve [L]); // interval Each number in the number of 
        return VE [L] + (X- . 1 ) / Ti; // (. 1-X ) Effect on behalf of itself remove 
    }
     int MID = (L + R & lt) >> . 1 ;
     IF (the lazy [RT]) 
    { 
        Deal (RT << . 1 , L, MID, the lazy [RT]); 
        Deal (RT << . 1 | . 1 , MID + . 1 , R & lt, the lazy [RT]); 
        the lazy [RT] = 0 ; 
    } 
    IF (SZ [RT << . 1 ]> = X) return Query (L, MID, RT << . 1 , X);//证明在左区间
    else return Query(mid+1,r,rt<<1|1,x-sz[rt<<1]);
}
int main()
{
    int N;scanf("%d",&N);
    LL A1,B1,C1,M1;
    scanf("%lld%lld%lld%lld%lld%lld",&x[1],&x[2],&A1,&B1,&C1,&M1);
    LL A2,B2,C2,M2;
    scanf("%lld%lld%lld%lld%lld%lld",&y[1],&y[2],&A2,&B2,&C2,&M2);
    for(int i=1;i<=N;i++)
    {
        if(i>2)
        {
            x[i]=(A1*x[i-1]+B1*x[i-2]+C1)%M1;
            y[i]=(A2*y[i-1]+B2*y[i-2]+C2)%M2;
        }
        l[i]=min(x[i],y[i])+1;
        r[i]=max(x[i],y[i])+1;
        ve.push_back(l[i]);ve.push_back(r[i]+1);//注意这里加入的是R[i]+1
    }
    sort(ve.begin(),ve.end());
    ve.erase(unique(ve.begin(),ve.end()),ve.end());//排序去重
    LL sum=0;int cnt=ve.size();
    for(int i=1;i<=N;i++)
    {
        sum+=r[i]-l[i]+1;
        int L=lower_bound(ve.begin(),ve.end(),l[i])-ve.begin();
        int R=lower_bound(ve.begin(),ve.end(),r[i]+1)-ve.begin();
        Update(0,cnt-1,1,L,R-1);// Note here -1 
        the printf ( " % LLD \ n- " , Query ( 0 , the CNT- . 1 , . 1 , (+ SUM . 1 ) / 2 )); 
    } 
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/caijiaming/p/11348761.html