BZOJ 3932任务查询系统

题意

最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分。超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi。同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同。调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少。特别的,如果Ki大于第Xi秒正在运行的任务总数,则直接回答第Xi秒正在运行的任务优先级之和。上述所有参数均为整数,时间的范围在1到n之间(包含1和n)。

主席数差分一下,再每个节点记一个和就好了

代码

#include<cstdio>
#include<cstring>
#include<algorithm> 
#include<cstdlib>
#include<vector>
#include<queue>
#define For(i,j,k) for(int i=(j);i<=(int)k;i++)
#define Forr(i,j,k) for(int i=(j);i>=(int)k;i--)
#define Rep(i,u) for(int i=Begin[u],v=to[i];i;i=Next[i],v=to[i])
#define Set(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define ll long long 
#define getchar getchar_unlocked 
#define L(i) (T[i].s[0])
#define R(i) (T[i].s[1])
#define S(i) (T[i].sum)
#define s(i) (T[i].ss)
using namespace std;
const int N=100001,INF=0x3f3f3f3f;
int m,n;
template <class T>inline void read(T &x){
    x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
int P[N];
vector<int>ins[N],del[N];
struct A{
    ll x;
    int id;
    bool operator <(const A &r)const{
        return x<r.x;
    }
};
struct node{
    int s[2],sum;
    ll ss;
};
struct cht{
    node T[N*40];
    int rk[N],rt[N],cnt,n,tot,nn;
    A a[N];
    #define mid ((l+r)>>1)
    inline void init(int num,int S){
        cnt=0;nn=num,tot=1;
        For(i,1,nn)a[i].id=i,a[i].x=P[i];
        sort(a+1,a+nn+1);
        For(i,1,nn)rk[a[i].id]=i;
        For(i,1,S){
            rt[i]=rt[i-1];
            For(j,0,ins[i].size()-1)
                insert(rk[ins[i][j]],rt[i],1,nn,1);
            For(j,0,del[i].size()-1)
                insert(rk[del[i][j]],rt[i],1,nn,-1);
        }
    }
    void insert(int val,int &x,int l,int r,ll add){
        T[++cnt]=T[x],x=cnt,S(x)+=add,s(x)+=add*a[val].x;
        if(l==r)return ;
        if(val<=mid)insert(val,L(x),l,mid,add);
        else insert(val,R(x),mid+1,r,add);
    }
    ll query(int x,ll k){
        k=min((ll)S(rt[x]),k);
        return query(rt[x],1,nn,k); 
    }
    ll query(int u,int l,int r,int k){
        int sum=S(L(u));
        if(l==r)return s(u);
        if(k<=sum)return query(L(u),l,mid,k);
        else return query(R(u),mid+1,r,k-sum)+s(L(u));
    }
}t;
int main(){
    ll pre=1;
    read(m),read(n);
    For(i,1,m){
        ll s,e,p;
        read(s),read(e),read(p);
        P[i]=p;
        ins[s].pb(i);
        del[e+1].pb(i);
    }
    t.init(m,n);    
    For(i,1,n){
        ll x,a,b,c,k;
        read(x),read(a),read(b),read(c);
        k=(a*pre+b)%c+1;
        printf("%lld\n",pre=t.query(x,k));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值