• BZOJ3932: [CQOI2015]任务查询系统 主席树


     

    3932: [CQOI2015]任务查询系统

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 4869  Solved: 1652
    [Submit][Status][Discuss]

    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+(Ai*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

    HINT

     

    样例解释

    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的一个排列

     

     

    Source

    题解:这是一个主席树的题目,首先需要读清楚题目,有n个任务,所以可以通过离散化使得变成n个优先级,因为一个任务是在一段区间中出现的,所以很显然我们可以用到差分思想,在st++,end+1处--。作为一种高级的前缀和,很容易想到我们要以时间顺序依次建立每颗权值线段树,线段树维护的是某一时刻某一个优先级出现的次数。这里要注意的是时间不一定连续,所以在同一时间的就以当前时间的root开始建树,否则沿用前一时刻的,写成代码可以对于每一个i都将root[i]=root[i-1]就行。 PS:在试着少看题解,不然比赛时仍旧不会做,想的时候想到了差分,离散化,按照时间建树,以及主席树维护的肯定是优先级的出现次数,但是还是不太清楚怎么写。
    #include<bits/stdc++.h>
    #define ll long long
    #define pb push_back
    #define _mp make_pair
    #define ldb long double
    using namespace std;
    const int maxn=2e5+100;
    inline 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;
    }
    struct node
    {
        ll l,r;
        ll sum,v;
    }no[maxn*40];
    struct sr
    {
        int x,num,tp,val;
    }sf[maxn*2];
    int id[maxn],nid[maxn],pri[maxn];
    ll root[maxn<<1];
    int cnt=0,tot=0,n,m;
    bool cmp1( int a, int b){
        return pri[a]<pri[b];
    }
    bool cmp2(const sr& a,const sr& b)
    {
        return a.x<b.x;
    }
    void insert(ll& now,int l,int r,int pl,int val,int type)
    {
        no[++cnt]=no[now];
        now=cnt;
        no[now].v+=type;
        no[now].sum+= val;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(pl<=mid)insert(no[now].l,l,mid,pl,val,type);
        else if(pl>mid)insert(no[now].r,mid+1,r,pl,val,type);
    }
    ll query(ll x,int l,int r,ll k)
    {
        if(l==r)
        {
            return no[x].sum;
        }
        int mid=(l+r)>>1;
        ll tmp=0;
        ll ss=no[no[x].l].v;
        if(ss>=k)
        {
            tmp+=query(no[x].l,l,mid,k);
        }
        else
        {
            tmp+=no[no[x].l].sum;
            tmp+=query(no[x].r,mid+1,r,k-ss);
        }
        return tmp; 
    }
    int pp,qq,rr,ss;
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)
        {
            pp=read();qq=read();rr=read();
            pri[i]=rr;id[i]=i;
            sf[++tot].x=pp;sf[tot].val=rr;sf[tot].tp=1;
            sf[++tot].x=qq+1;sf[tot].val=-rr;sf[tot].tp=-1; 
        }
        sort(id+1,id+1+n,cmp1);
        for(int i=1;i<=n;i++)nid[id[i]] =i;
    //    for(int i=1;i<=n;i++)cout<<nid[i]<<endl;
        for(int i=1;i<=tot;i+=2)
        {
            sf[i].num=sf[i+1].num=nid[(i+1)/2];
        }
        sort(sf+1,sf+1+tot,cmp2);
        int j=1;
        for(int i=1;i<=m;i++)
        {
            root[i]=root[i-1];
            while(sf[j].x==i)
            {
                insert(root[i],1,n,sf[j].num,sf[j].val,sf[j].tp);
                j++;
            }
        }
        //cout<<cnt<<endl;
        ll pre=1;
        for(int i=1;i<=m;i++)
        {
            ss=read();pp=read();qq=read();rr=read();
            ll tmp=1+(pp*pre+qq)%rr;
            //cout<<tmp<<endl;
            pre=query(root[ss],1,n,tmp);
            printf("%lld
    ",pre);
        }
    } 
     
    

      

  • 相关阅读:
    NX二次开发-UFUN UF_UI_add_to_class_sel将UDOTestClass类的显示名称加入到类选择对话框的类列表中
    NX二次开发-UFUN创建管道UF_MODL_create_tube
    NX二次开发-UFUN获得工作视图的tag UF_VIEW_ask_work_view
    SQLyog/Mysql怎么修改用户/root密码【转载】
    MySQL返回来的值都是字符串类型,还原每个字段【转载】
    NX二次开发-NX访问MySQL数据库(增删改查)
    NX二次开发-ug表达式函数ug_find_file读取当前prt所在路径【转发】
    QT界面开发-QProgressBar【转载】
    QT界面开发-使用new QComboBox添加触发事件
    QT界面开发-窗口滚动条【转发】
  • 原文地址:https://www.cnblogs.com/intwentieth/p/9681295.html
Copyright © 2020-2023  润新知