BZOJ 3932: [CQOI2015]任务查询系统

一道可持久化线段树裸题,搞出来每一个位置的权值线段树然后正常查找就行了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<iomanip>
#include<ctime>
#include<cmath>
#include<algorithm>
using namespace std;
struct xianduan
{
    xianduan *ls,*rs;
    int size;
    long long sum;
    void *operator new(size_t,xianduan *_,xianduan *__,int ___,long long ____)
    {
        static xianduan *C,*mempool;
        if(C==mempool) mempool=(C=new xianduan[1<<15])+(1<<15);
        C->ls=_;
        C->rs=__;
        C->size=___;
        C->sum=____;
        return C++;
    }
    friend xianduan* maketree(xianduan *o,int l,int r,int pos,int c_size,long long c_sum)
    {
        int mid=l+r>>1;
        if(l==r) return new(0x0,0x0,o->size+c_size,o->sum+c_sum)xianduan;
        if(pos<=mid) return new(maketree(o->ls,l,mid,pos,c_size,c_sum),o->rs,o->size+c_size,o->sum+c_sum)xianduan;
        else return new(o->ls,maketree(o->rs,mid+1,r,pos,c_size,c_sum),o->size+c_size,o->sum+c_sum)xianduan;
    }
    friend long long query(xianduan *o,int l,int r,int k)
    {
        int mid=l+r>>1;
        if(l==r) return k*l;
        if(o->ls->size>=k) return query(o->ls,l,mid,k);
        else return query(o->rs,mid+1,r,k-o->ls->size)+o->ls->sum;
    }
}*root[10000011];
struct change
{
    int pos;
    int tim,lei;
    long long ying;
    bool operator <(change b) const
    {
        return tim<b.tim;
    }
}changes[200020];
int top=0;
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int maxx=0;
    for(int i=1;i<=n;i++)
    {
        int x,y,v;
        scanf("%d%d%d",&x,&y,&v);
        if(x>maxx) maxx=x;
        if(y+1>maxx) maxx=y+1;
        changes[++top].tim=x;
        changes[top].pos=v;
        changes[top].lei=1;
        changes[top].ying=v;
        changes[++top].tim=y+1;
        changes[top].pos=v;
        changes[top].lei=-1;
        changes[top].ying=-v;
    }
    sort(changes+1,changes+1+top);
    int wz=1;
    root[0]=new(0x0,0x0,0,0ll)xianduan;
    root[0]->ls=root[0]->rs=root[0];
    for(int i=1;i<=m;i++)
    {
        root[i]=root[i-1];
        while(changes[wz].tim==i)
        {
            root[i]=maketree(root[i],1,10000000,changes[wz].pos,changes[wz].lei,changes[wz].ying);
            wz++;
        }
    }
    long long ans=1;
    for(int i=1;i<=m;i++)
    {
        int x,aa,bb,cc;
        scanf("%d%d%d%d",&x,&aa,&bb,&cc);
        int k=1+(aa*ans+bb)%cc;
        if(k>root[x]->size) k=root[x]->size;
        ans=query(root[x],1,10000000,k);

        printf("%lld\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值