[BZOJ3932] [CQOI2015]任务查询系统

题目描述

Description

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

Input

输入文件第一行包含两个空格分开的正整数m和n,分别表示任务总数和时间范围。接下来m行,每行包含三个空格
分开的正整数Si、Ei和Pi(Si≤Ei),描述一个任务。接下来n行,每行包含四个空格分开的整数Xi、Ai、Bi和Ci,
描述一次查询。查询的参数Ki需要由公式 Ki=1+(A*Pre+Bi) mod Ci计算得到。其中Pre表示上一次查询的结果,
对于第一次查询,Pre=1。

Output

输出共n行,每行一个整数,表示查询结果。

Sample Input

4 3
1 2 6
2 3 3
1 3 2
3 3 4
3 1 3 2
1 1 3 4
2 2 4 3

Sample Output

2
8
11

对于100%的数据,1≤m,n,Si,Ei,Ci≤100000,0≤Ai,Bi≤100000,1≤Pi≤10000000,Xi为1到n的一个排列

题目分析

差分+主席树
按照时间顺序建造主席树 对于[S,E]的任务 在S时间主席树+1 (E+1)时间主席树-1
拿vector存一下就好了

#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std;
int n,m;
int val[100100];
vector<int>b[100100];
struct your
{
    int lson,rson;
    int size;
    long long sum;
}a[10000010];
int root[100100],cnt;
void update(int x,int &y,int c,int l,int r)
{   
    y=++cnt;
    a[y]=a[x];
    a[y].sum=(long long) a[y].sum+c; 
    a[y].size+= (c>=0)?1:-1;
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(abs(c)<=mid) update(a[x].lson,a[y].lson,c,l,mid);
    else update(a[x].rson,a[y].rson,c,mid+1,r);
}
long long ask(int l,int r,int c,int x)
{
    if(!x) return 0;
    if(a[x].size<=c)
        return a[x].sum;
    if(l==r) return (long long) c*l;
    int mid=(l+r)>>1;
    if(c<=a[a[x].lson].size) return ask(l,mid,c,a[x].lson);
    else return a[a[x].lson].sum+ask(mid+1,r,c-a[a[x].lson].size,a[x].rson);
}
int main()
{   
    scanf("%d%d",&n,&m);
    for(int x,y,c,i=1;i<=n;i++)
    {
        scanf("%d%d%d",&x,&y,&c);
        b[x].push_back(c);
        b[y+1].push_back(-c);
    }
    for(int i=1;i<=m;i++)
    {
        root[i]=root[i-1];
        for(int j=0;j<b[i].size();j++)
            update(root[i],root[i],b[i][j],1,1000000000);
    }
    long long ans=1;
    for(int x,ai,bi,ci,i=1;i<=m;i++)
    {
        scanf("%d%d%d%d",&x,&ai,&bi,&ci);
        int ki=1+(ai%ci*ans+bi)%ci;
        ans=ask(1,1000000000,ki,root[x]);
        printf("%lld\n",ans);
    }
    return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注