zoukankan      html  css  js  c++  java
  • [CQOI2015]任务查询系统

    # 洛谷题目链接:[[CQOI2015]任务查询系统](https://www.luogu.org/problemnew/show/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的一个排列

    简述一下题意:给出一个区间(长度最长为(10^6)),以及m次区间修改和区间的大小n.然后是n次询问,求出包含x位置的所有区间中的前k个的和.强制在线.

    因为序列的长度并不长,所以我们可以考虑用一些数据结构来记录下覆盖点下标为pos的所有区间.然后还要求前k小的和,这里可以用主席树来维护.

    下面直接讲一下做法吧:主席树+差分

    • 将每个任务看作是在区间[l,r]上加一个值(区间修改).
    • 将一个区间[l,r]的修改为在下标为l的位置+1,在r+1的位置-1.
    • 将所有修改的位置按照位置顺序排序,每个下标都储存一些区间修改的值.
    • 在修改主席树和的时候直接加上一次修改的值乘以它的符号(前面记录的加或减),这样就统计出了每个位置的和.
    • 统计时直接按照主席树的查询方式查询.

    因为一个下标的位置上有可能有多次修改,所以要一起记录到同一个下标位置上,但是又只需要记录n个版本的主席树,所以可以用一个数组辅助一下.

    下面贴一下代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=100000+5;
    typedef long long lol;
    
    int n, m, cnt = 0, cntm = 0, size;
    int w[N*2], rk[N*2];
    int root[N], c[N*2];
    
    struct task{
        int pos, f, val;
    }mi[N*3];
    
    struct president_tree{
        int ls, rs, sz;
        lol sum;
    }t[N*40];//数组开大点
    
    int gi(){
        int ans = 0 , f = 1; char i = getchar();
        while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
        while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
        return ans * f;
    }
    
    bool cmp(task a,task b){
        return a.pos < b.pos;
    }
    
    void updata(int &node,int last,int f,int pos,int l=1,int r=m){
        node = ++cnt; t[node] = t[last];
        t[node].sum += (lol) f*w[pos]; t[node].sz += f;
        if(l == r) return; int mid = (l+r>>1);
        if(pos <= mid) updata(t[node].ls , t[last].ls , f , pos , l , mid);
        else updata(t[node].rs , t[last].rs , f , pos , mid+1 , r);
    }
    
    lol query(int node,int k,int l=1,int r=m){
        if(l == r) return t[node].sum/t[node].sz*(lol)k;
        int mid = (l+r>>1), s = t[t[node].ls].sz;
        if(k <= s) return query(t[node].ls,k,l,mid);
        else return t[t[node].ls].sum + query(t[node].rs,k-s,mid+1,r);
    }
    
    int main(){
        //freopen("data.in","r",stdin);
        int x, y, z, pos; n = gi(); m = gi();
        for(int i=1;i<=n;i++){
    		x = gi(); y = gi(); z = gi();
    		mi[++cntm].pos = x;   mi[cntm].f = 1;  mi[cntm].val = z;
    		mi[++cntm].pos = y+1; mi[cntm].f = -1; mi[cntm].val = z;//记录每个位置上的修改
    		w[i] = z;
        }
        sort(w+1 , w+n+1); sort(mi+1 , mi+cntm+1 , cmp);
        for(int i=1;i<=cntm;i++)
    		rk[i] = lower_bound(w+1,w+n+1,mi[i].val)-w;
    	c[0] = 0;
    	for(int i=1, j=1;i<=m;i++){
    		while(j<=cntm && mi[j].pos == i)
    		    updata(c[j] , c[j-1] , mi[j].f , rk[j]) , j++;//将同一位置上的修改加到同一个下标
    		root[i] = c[j-1];
        }
        lol lans = 1, kth;
        for(int i=1;i<=m;i++){
    		pos = gi(); x = gi(); y = gi(); z = gi();
    		kth = (x*lans+y) % z + 1;
    		if(t[root[pos]].sz <= kth) lans = t[root[pos]].sum;
    		else lans = (lol) query(root[pos],kth);
    		//printf("kth=%lld size=%d
    ",kth,t[root[pos]].sz);
    		printf("%lld
    ",lans);
        }
        return 0;
    }
    
  • 相关阅读:
    20165334 实验一 Java开发环境的熟悉
    20165334 《java程序设计》第5周学习总结
    20165334《java程序设计》第4周学习总结
    20165334《java程序设计》第三周学习总结
    20165334 预备作业3 Linux及学习
    20165334 学习基础与c语言学习心得
    20165228 实验一 Java开发环境的熟悉
    20165228 2017-2018-2 《Java程序设计》第5周学习总结
    20165228 2017-2018-2 《Java程序设计》第4周学习总结
    20165228 2017-2018-2 《Java程序设计》第3周学习总结
  • 原文地址:https://www.cnblogs.com/BCOI/p/8807187.html
Copyright © 2011-2022 走看看