Chairman Tree Difference Array of P3168 [CQOI2015] Task Query System

Keywords: PHP

Now there is a group of tasks, each task has a start and end time and a priority, give you the start and end time and priority of all tasks, ask you at a certain point in time the minimum priority k priority sum.

 

Ordinary chair tree is a single point modified interval query.

 

We can use difference array to do prefix sum of interval query to 1-i.

 

Note that the way the copy node does not simply copy T, and son t num

Repeated cumulative operations are written as T[i] T[i], not T[i-1] T[i]

The scope of the Presidential Tree is only related to the discrete subscript of the data put in it, and has nothing to do with the historical version number.

The time of this question is the historical version number, which has nothing to do with the scope of the Presidential Tree.

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
typedef pair<int,int>pii;
//////////////////////////////////
const int N=2e6+10;
int son[N<<5][2];
ll t[N<<5],num[N<<5];
int T[N<<5],ncnt;

struct node {int x,v;ll flag; } a[N];
int n,m;
ll b[N];
void build(int l,int r,int &pos)
{
    pos=++ncnt;
    if(l==r)return ;
    int m=l+r>>1;
    build(l,m,son[pos][0]);
    build(m+1,r,son[pos][1]);
}
void up(int x,int flag,int l,int r,int pre,int &pos)
{
    pos=++ncnt;
    son[pos][0]=son[pre][0];
    son[pos][1]=son[pre][1];
    t[pos]=t[pre]+flag*b[x];
    num[pos]=num[pre]+flag;
    
    if(l==r){return ;}
    int m=l+r>>1;
    if(x<=m)up(x,flag,l,m,son[pos][0],son[pos][0]);
    else up(x,flag,m+1,r,son[pos][1],son[pos][1]);
}

int qsum(int k,int l,int r,int pos)
{
    if(l==r)return min(k*t[pos]/num[pos],t[pos]);
    if(num[pos]<=k)return t[pos];
    int m=l+r>>1;
    if(num[son[pos][0]]>=k)return qsum(k,l,m,son[pos][0]);
    else return t[son[pos][0]]+qsum(k-num[son[pos][0]],m+1,r,son[pos][1]);
}
void cpy(int &pos,int pre)
{
    pos=++ncnt;
    son[pos][0]=son[pre][0];
    son[pos][1]=son[pre][1];
    t[pos]=t[pre];
    num[pos]=num[pre];
}
int main()
{
    scanf("%d%d",&n,&m);
    rep(i,1,n)
    {
        int x,y;ll z;scanf("%d%d%lld",&x,&y,&z);
        a[2*i-1]=(node){x,z,1};
        a[2*i  ]=(node){y+1,z,-1};
        b[i]=z;
    }
    sort(b+1,b+1+n);
    int nn=unique(b+1,b+1+n)-b-1;
    sort(a+1,a+1+2*n,[](node a,node b){return a.x<b.x;}  );
    build(1,nn,T[0]);
    
    int pos=1;
    rep(i,1,m)
    {
        cpy(T[i],T[i-1]);
        while(pos<=2*n&&a[pos].x==i)
        {
            up(lower_bound(b+1,b+1+nn,a[pos].v)-b,a[pos].flag,1,nn,T[i],T[i]); pos++;//Notice if this is written as T[i-1],T[i]  Can't satisfy repeated updates
        }
    }
    ll ans=1,A,B,C,x,k;
    rep(j,1,m)
    {
        scanf("%lld%lld%lld%lld",&x,&A,&B,&C);
        k=1+(A*ans+B)%C;
        if(k>=num[T[x]]) ans=t[T[x]];
        else
        ans=qsum((int)k,1,nn,T[x]);
        printf("%lld\n",ans);
    }
    return 0;
}

Posted by FlyingIsFun1217 on Sun, 13 Oct 2019 13:53:53 -0700