BZOJ_3110_[Zjoi2013]K large number query_overall bisection + tree array

BZOJ_3110_[Zjoi2013]K large number query_overall bisection + tree array

Description

There are N positions, M operations. There are two kinds of operations. If each operation is in the form of 1 abc, it means from the ath position to the bth position, and a number c is added to each position.
If it is in the form of 2 abc, it means that the query is from the ath position to the bth position. position, what is the C-th largest number.

Input

The first line N, M
next M lines, each line is like 1 abc or 2 abc

Output

output the result of each query

Sample Input

2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3

Sample Output

1
2
1

 solve(b,e,l,r) means to process the query of b~e, the answer is between l~r, and the insertion is processed at the same time, and the weight range is l~r.
Take all operations offline, while keeping operations in timestamp order at any time.
The two-point answer mid, if the inserted number is greater than mid, insert it (interval addition), otherwise throw it to the left.
For the query like a normal overall bisection, query the interval sum, and then go left or right.
 
Code:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef unsigned int uint;
#define N 50050
int n, m, flg [N], ans [N];
struct Bit {
    uint c[N];
    void fix(int x,uint v) { for(;x<=n;x+=x&(-x)) c[x]+=v; }
    uint inq(int x) { uint re=0;for(;x;x-=x&(-x)) re+=c[x];return re;}
}A,B;
struct Q {
    int a,b,c,d,id;
}q[N],t[N];
void update(int x,int y,uint v) {
    A.fix(x,v); A.fix(y+1,-v);
    B.fix(x,x*v); B.fix(y+1,-(y+1)*v);
}
uint query(int x,int y) {
    return A.inq(y)*(y+1)-B.inq(y)-A.inq(x-1)*x+B.inq(x-1);
}
void solve(int b,int e,int l,int r) {
    int i;
    if(b>e) return ;
    if(l==r) {
        for(i=b;i<=e;i++) if(q[i].a==2) ans[q[i].id]=l;
        return ;
    }
    int mid=(l+r)>>1,lp=b-1,rp=e+1;
    for(i=b;i<=e;i++) {
        if(q[i].a==1) {
            if(q[i].d<=mid) t[++lp]=q[i];
            else update(q[i].b,q[i].c,1),t[--rp]=q[i];
        }else {
            uint tmp=query(q[i].b,q[i].c);
            if(q[i].d<=tmp) t[--rp]=q[i];
            else q[i].d-=tmp,t[++lp]=q[i];
        }
    }
    for(i=b;i<=e;i++) {
        if(q[i].a==1&&q[i].d>mid) update(q[i].b,q[i].c,-1);
    }
    for(i=b;i<=lp;i++) q[i]=t[i];
    for(i=rp;i<=e;i++) q[e-i+rp]=t[i];
    solve(b,lp,l,mid);
    solve(rp,e,mid+1,r);
}
int main() {
    scanf("%d%d",&n,&m);
    int i;
    for(i=1;i<=m;i++) {
        scanf("%d%d%d%d",&q[i].a,&q[i].b,&q[i].c,&q[i].d); q[i].id=i;
        if(q[i].a==2) flg[i]=1;
    }
    solve(1,m,-n,n);
    for(i=1;i<=m;i++) if(flg[i]) printf("%d\n",ans[i]);
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325017991&siteId=291194637
Recommended