AC日记——任务查询系统 洛谷 P3168

题目描述

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

输入输出格式

输入格式:

 

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

 

输出格式:

 

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

 

输入输出样例

输入样例#1:
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
输出样例#1:
2
8
11

说明

样例解释

K1 = (1*1+3)%2+1 = 1

K2 = (1*2+3)%4+1 = 2

K3 = (2*8+4)%3+1 = 3

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

 

 

思路:

  可持久化线段树(坑很多很多,诸位小心)

 

来,上代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
 
#define maxn 100001
#define LL long long
 
using namespace std;
 
struct T_do {
    LL time,pi,dis;
};
struct T_do do_[maxn<<2];
 
struct TreeNodeType {
    LL l,r,dis,sum,bel;
     
    TreeNodeType *left,*right;
};
struct TreeNodeType *null,*root[maxn<<1];
 
LL if_z,n,m,num,hash[maxn<<1],size,bef;
 
char Cget;
 
bool if_[maxn<<1];
 
inline void read_LL(LL &now)
{
    if_z=1,now=0,Cget=getchar();
    while(Cget>'9'||Cget<'0')
    {
        if(Cget=='-') if_z=-1;
        Cget=getchar();
    }
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
    now*=if_z;
}
 
void tree_build(TreeNodeType *&now,LL l,LL r)
{
    now=new TreeNodeType;
    now->l=l,now->r=r;
    now->dis=0,now->sum=0;
    now->bel=0;
    now->left=null;
    now->right=null;
    if(l==r) return ;
    LL mid=(l+r)>>1;
    tree_build(now->left,l,mid);
    tree_build(now->right,mid+1,r);
}
 
bool cmp(struct T_do a1,struct T_do a2)
{
    return a1.time<a2.time;
}
 
void tree_change(TreeNodeType *&pre,TreeNodeType *&now,LL bel,LL dis,LL sum,LL to)
{
    now=new TreeNodeType;
    now->sum=pre->sum+sum;
    now->l=pre->l,now->r=pre->r;
    now->bel=bel,now->dis=pre->dis+dis;
    now->left=pre->left,now->right=pre->right;
    if(now->l==now->r) return ;
    LL mid=(now->l+now->r)>>1;
    if(to>mid) tree_change(pre->right,now->right,bel,dis,sum,to);
    else tree_change(pre->left,now->left,bel,dis,sum,to);
}
 
void tree_change_(TreeNodeType *&now,LL bel,LL dis,LL sum,LL to)
{
    if(now->bel!=bel)
    {
        TreeNodeType *tmp=new TreeNodeType;
        tmp->l=now->l,tmp->r=now->r;
        tmp->dis=now->dis,tmp->bel=bel;
        tmp->sum=now->sum,tmp->left=now->left;
        tmp->right=now->right;
        now=tmp;
    }
    now->dis+=dis,now->sum+=sum;
    if(now->l==now->r) return ;
    LL mid=(now->l+now->r)>>1;
    if(to>mid) tree_change_(now->right,bel,dis,sum,to);
    else tree_change_(now->left,bel,dis,sum,to);
}
 
LL tree_query(TreeNodeType *now,LL k)
{
    if(now->l==now->r) return now->sum/now->dis*k;
    if(k<=now->left->dis) return tree_query(now->left,k);
    else return tree_query(now->right,k-now->left->dis)+now->left->sum;
}
 
int main()
{
    read_LL(m),read_LL(n);
    LL pi,ai,bi;
    for(LL i=1;i<=m;i++)
    {
        read_LL(ai),read_LL(bi),read_LL(pi);
        num++,do_[num].dis=1,do_[num].pi=pi,do_[num].time=ai;
        num++,do_[num].dis=-1,do_[num].pi=-pi,do_[num].time=bi+1;
        hash[i]=pi;
    }
    sort(hash+1,hash+m+1);
    size=unique(hash+1,hash+m+1)-hash-1;
    null=new TreeNodeType;
    null->l=0,null->r=0;
    null->dis=0,null->sum=0;
    null->bel=0;
    null->left=null;
    null->right=null;
    tree_build(root[0],1,size);
    sort(do_+1,do_+num+1,cmp);
    for(LL i=1;i<=num;i++)
    {
        for(LL j=do_[i-1].time+1;j<do_[i].time;j++)
        {
            root[j]=root[do_[i-1].time];
        }
        LL pi_;
        if(do_[i].pi<0) pi_=lower_bound(hash+1,hash+size+1,-do_[i].pi)-hash;
        else pi_=lower_bound(hash+1,hash+size+1,do_[i].pi)-hash;
        if(!if_[do_[i].time])
        {
            if_[do_[i].time]=true;
            tree_change(root[do_[i-1].time],root[do_[i].time],do_[i].time,do_[i].dis,do_[i].pi,pi_);
        }
        else
        {
            tree_change_(root[do_[i].time],do_[i].time,do_[i].dis,do_[i].pi,pi_);
        }
    }
    LL pre_=1;
    LL xi,ci;
    for(LL i=1;i<=n;i++)
    {
        read_LL(xi),read_LL(ai),read_LL(bi),read_LL(ci);
        pre_=1+((ai*pre_+bi)%ci);
        LL res;
        if(root[xi]->dis>pre_) res=tree_query(root[xi],pre_);
        else res=root[xi]->sum;
        cout<<res;
        putchar('\n');
        pre_=res;
    }
    return 0;
}

 

posted @ 2017-02-01 17:08  IIIIIIIIIU  阅读(381)  评论(0编辑  收藏  举报