Bzoj3932--Cqoi2015任务查询系统

按时间来建一棵主席树

下一个时间和上一个时间的改变就是那个时间点任务的改变

具体我们可以把任务拆成两个时间点,前一个代表加上这个数,后一个是删除这个数

代码:

#include<bits/stdc++.h>
#define MAXN 100005
#define MOD 1000000007
#define LINF 100000000000000ll
#define INF 1000000000
#define LL long long 
using namespace std;

inline int _abs(int a) {return a>0?a:-a;}

const int mp=10000000;
struct event{
    int pos,k;
    bool operator < (event b) const {
        return pos<b.pos;
    }
    inline void in(int a,int b) {
        pos=a;k=b;
    }
}ev[MAXN*3];
int m,n;

namespace Chairman_Tree{
    const int L=0,R=1;
    int root[MAXN],sz;
    struct Node{
        int s,son[2],sum;
    }x[MAXN*70];
    
    void Build_Tree(int l,int r,int &now,int fr,int v,int p,bool c) {
        if(c) now=++sz,x[now]=x[fr];
        x[now].s+=p;x[now].sum+=p*v;
        if(l==r) return;
        int mid=l+r>>1;
        if(v>mid) Build_Tree(mid+1,r,x[now].son[R],x[fr].son[R],v,p,x[now].son[R]==x[fr].son[R]);
        else Build_Tree(l,mid,x[now].son[L],x[fr].son[L],v,p,x[now].son[L]==x[fr].son[L]);
    }
    void Build(int x,int y,int p,bool c) {
        Build_Tree(1,mp,root[x],root[y],_abs(p),p>0?1:-1,c);
    }
    
    LL Query(int pos,int k) {
        LL ret=0;
        int now=root[pos],l=1,r=mp,mid;
        if(k>=x[now].s) return x[now].sum;
        while(l!=r) {
            mid=l+r>>1;
            if(x[x[now].son[L]].s<k) k-=x[x[now].son[L]].s,ret+=x[x[now].son[L]].sum,now=x[now].son[R],l=mid+1;
            else now=x[now].son[L],r=mid;
        }
        return ret+k*l;
    }
}

using namespace Chairman_Tree;

int main() {
    scanf("%d%d",&m,&n);
    for(int a,b,c,i=1;i<=m;i++) {
        scanf("%d%d%d",&a,&b,&c);
        ev[(i<<1)-1].in(a,c);
        ev[i<<1].in(b+1,-c);
    }
    sort(ev+1,ev+1+2*m);
    for(int now=1,i=1;i<=n;i++) {
        root[i]=++sz;
        x[root[i]]=x[root[i-1]];
        while(ev[now].pos==i) Build(i,i-1,ev[now].k,0),now++;
    }
    for(LL pos,a,b,c,pre=1,i=1;i<=n;i++) {
        scanf("%lld%lld%lld%lld",&pos,&a,&b,&c);
        a=1+(a*pre+b)%c;
        pre=Query(pos,a);
        printf("%lld\n",pre);
    }
    return 0;
}

 

posted @ 2016-10-09 14:51  ihopenot  阅读(242)  评论(0编辑  收藏  举报