• 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('
    ');
            pre_=res;
        }
        return 0;
    }
  • 相关阅读:
    为什么使用enable_shared_from_this——shared_ptr两类错误
    More Effective C++ Item14:明智运用exception specifications
    用“双优先队列”方法解决双/多指标的规划问题
    彻底理解AC多模式匹配算法
    CentOS7安装MySQL
    CentOS7配置本地Yum源
    数组
    比较运算符
    申明变量
    相等运算符==与等同运算符===
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6360126.html
Copyright © 2020-2023  润新知