BZOJ 3932 [CQOI2015]任务查询系统 ——可持久化线段树

时间:2024-10-19 11:35:44

【题目分析】

主席树,维护区间大小以及权值之和。

但是细节确实要琢磨很久,WA了几次。

【代码】

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>

#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>

using namespace std;

#define maxn 300005
#define mlog 40
#define inf (0x3f3f3f3f)
#define ll long long

ll read()
{
    ll x=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

ll llread()
{
    ll x=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

ll rt[maxn],ls[maxn*mlog],rs[maxn*mlog],siz[maxn*mlog],tot=0,n,m;
struct eve{ll p,opt;}a[maxn];
vector <eve> v[maxn];
ll sum[maxn*mlog];
ll b[maxn],top=0,cnt=0;
ll pre=1;

/*
void ins(ll o1,ll &o2,ll l,ll r,ll x,ll f)
{
    o2=++tot;
    siz[o2]=siz[o1]+f;
    sum[o2]=sum[o2]+(ll)b[x]*f;
    if (l==r) return ;
    ll mid=(l+r)/2;
    if (x<=mid)  ins(ls[o1],ls[o2],1,mid,x,f),rs[o2]=rs[o1];
    else ins(rs[o1],rs[o2],mid+1,r,x,f),ls[o2]=ls[o1];
//  sum[o2]=sum[ls[o1]]+sum[ls[o2]];
}
*/

ll ins (ll o1,ll l,ll r,ll x,ll f)
{
    ll now=++tot;
    siz[now]=siz[o1]+f;
    sum[now]=sum[o1]+b[x]*f;
    if (l==r) return now;
    ll mid=(l+r)/2;
    if (x<=mid) ls[now]=ins(ls[o1],l,mid,x,f),rs[now]=rs[o1];
    else rs[now]=ins(rs[o1],mid+1,r,x,f),ls[now]=ls[o1];
    return now;
}

ll query(ll o,ll l,ll r,ll x)
{
    if (x>=siz[o]) return sum[o];
    if (l==r) return min(x,siz[o])*b[l];
    ll tmp=siz[ls[o]];
    if (tmp>=x) return query(ls[o],l,(l+r)/2,x);
    else return sum[ls[o]]+query(rs[o],(l+r)/2+1,r,x-tmp);
}

int main()
{
    n=read();m=read();
    for (ll i=1;i<=n;++i)
    {
        ll x=read(),y=read(),z=read();
        if (x<=m)
        {
            a[++cnt].p=z;
            a[cnt].opt=1;
            v[x].push_back(a[cnt]);
        }
        if (y+1<=m)
        {
            a[++cnt].p=z;
            a[cnt].opt=-1;
            v[y+1].push_back(a[cnt]);
        }
        b[++top]=z;
    }
    sort(b+1,b+top+1);
    top=unique(b+1,b+top+1)-b-1;
    for (ll i=1;i<=m;++i)
    {
        rt[i]=rt[i-1];
        for (ll j=0;j<v[i].size();++j)
            rt[i]=ins(rt[i],1,top,lower_bound(b+1,b+top+1,v[i][j].p)-b,v[i][j].opt);
    }
    for (ll i=1;i<=m;++i)
    {
        ll k,x,a,b,c;
        x=llread();a=llread();b=llread();c=llread();
        k=1+(a*pre+b)%c;
//      if (i==m) k++;
        printf("%lld\n",pre=query(rt[x],1,top,k));
    }
}