• [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+(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的一个排列

    正在学主席树。。听说这个题是个模板题就跑去做了。。
    如果你不知道什么是主席树的话建议出门左转去学。。
    对于每一个时间点我们建一个版本的权值线段树,每个线段树记录当前结点的任务数与这个结点的任务优先级之和。
    一个任务从i到j的话就给第i个版本++,第j+1个版本--;
    但是我们需要考虑几个事情
    1.pi太大,需要离散化,这是很显然的。
    2.修改了第x个版本的话后面所有版本都需要更改。
    对于1我的方法是把所有优先级先序排序去重然后依次放到数组里,因为排了序了所以它们的大小关系不会改变,然后通过二分找到离散化以后的值(但是被dalao嘲讽了)
    对于2我的方法是把所有操作按时间点大小先序排序,然后依次进行操作,如果当前的操作点比目前建的树要大那就开到那个时间点
    这个意思
    1 for(int i=1;i<=操作数;++i)
    2 {
    3     while(已经建了p个<a[i].time){建树(++p);}
    4     操作:加或减
    5 }

    因为我之后建的树会复制前面的树的值,而前面的树的操作都是已经做完了的,然后这个操作是2*m+n。

    当然这个也被dalao嘲讽了。。

    然后有一个东西要考虑(我就是错了这个)

    就是你查询到叶子结点的时候,它的任务数可能会比你剩下要查的个数要大,这样你就不需要取走全部了。。似乎是一个很显然的事情但我当时做却没想到。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #define N (100000+5)
      7 #define ll long long
      8 using namespace std;
      9 inline ll read()
     10 {
     11     char ch=getchar();ll kin=1,gi=0;
     12     while(ch>'9'||ch<'0'){if(ch=='-')kin=-1;ch=getchar();}
     13     while(ch>='0'&&ch<='9'){gi=gi*10+ch-48;ch=getchar();}
     14     return kin*gi;
     15 }
     16 struct tree
     17 {
     18     ll num;
     19     ll simple;
     20     ll son[2];
     21     ll l,r,fl;
     22 }d[5000005];
     23 struct naive
     24 {
     25     ll nic;
     26     ll st;
     27     bool fl;
     28 }ni[N*2];
     29 bool cmp(naive x,naive y)
     30 {
     31     return x.st<y.st;
     32 }
     33 ll n,m,siz,rt[N];
     34 ll sot[N],trl[N],kiz,fis,trik;
     35 ll pre=1,lis[N],ra,rig;
     36 void make(ll,ll,bool);
     37 ll query(ll,ll);
     38 void build(ll,ll,ll);
     39 void rut(ll);
     40 ll mmid(ll x)
     41 {
     42     ll l=1,r=kiz,res=0;
     43     while(l<=r)
     44     {
     45         ll mid=(l+r)>>1;
     46         if(trl[mid]<=x){l=mid+1;res=mid;}
     47         else r=mid-1;
     48     }
     49     return res;
     50 }
     51 int main()
     52 {
     53     m=read();n=read();
     54     for(ll i=1;i<=m;++i)
     55     {
     56 
     57         ni[++trik].st=read();ni[trik].fl=1;
     58         ni[++trik].st=read()+1;ni[trik].fl=0;
     59         ni[trik-1].nic=ni[trik].nic=read();
     60         sot[i]=ni[trik].nic;
     61     }
     62     sort(sot+1,sot+m+1);
     63     sort(ni+1,ni+trik+1,cmp);
     64     for(ll i=1;i<=m;++i)if(sot[i]!=sot[i-1])trl[++kiz]=sot[i];
     65     for(ll i=1;i<=trik;++i)
     66     {
     67         if(ni[i].st>n)break;
     68         while(fis<ni[i].st){rut(++fis);}
     69         ll rik=mmid(ni[i].nic);
     70         make(ni[i].st,rik,ni[i].fl);
     71     }
     72     while(fis<n){rut(++fis);}
     73     for(ll i=1;i<=n;++i)
     74     {
     75         ll sec=read();
     76         ll a,b,c,k;
     77         a=read();b=read();c=read();
     78         k=(a*pre+b)%c+1;
     79         printf("%lld
    ",pre=query(sec,k));
     80     }
     81     return 0;
     82 }
     83 ll query(ll x,ll y)
     84 {
     85     ll nw=rt[x],res=0;
     86     y=min(y,d[nw].simple);
     87     while(1)
     88     {
     89         if(y==0)break;
     90         if(d[nw].l==d[nw].r&&d[nw].simple>y){res+=trl[d[nw].l]*y;break;}
     91         if(d[nw].simple<=y){res+=d[nw].num;break;}
     92         if(d[d[nw].son[0]].simple<=y) y-=d[d[nw].son[0]].simple,res+=d[d[nw].son[0]].num,nw=d[nw].son[1];
     93         else nw=d[nw].son[0];
     94     }
     95     return res;
     96 }
     97 void make(ll x,ll num,bool p)
     98 {
     99     ll nw=rt[x];bool f;
    100     while(d[nw].l!=d[nw].r)
    101     {
    102         if(p)
    103         {d[nw].num+=trl[num];d[nw].simple++;}
    104         else
    105         {d[nw].num-=trl[num];d[nw].simple--;}
    106         f=(num>(d[nw].l+d[nw].r)>>1);
    107         if(d[d[nw].son[f]].fl!=x)
    108         {
    109             d[++siz]=d[d[nw].son[f]];
    110             d[nw].son[f]=siz;
    111             d[siz].fl=x;
    112         }
    113         nw=d[nw].son[f];
    114     }
    115         if(p)
    116         {d[nw].num+=trl[num];d[nw].simple++;}
    117         else
    118         {d[nw].num-=trl[num];d[nw].simple--;}
    119 }
    120 void rut(ll p)
    121 {
    122     ll x;
    123     x=rt[p]=++siz;
    124     d[x].l=1;d[x].r=kiz;d[x].fl=1;
    125     if(x>1)
    126     {
    127         d[rt[p]]=d[rt[p-1]];
    128         d[rt[p]].son[0]=d[rt[p-1]].son[0];
    129         d[rt[p]].son[1]=d[rt[p-1]].son[1];
    130     }
    131     else
    132     {
    133         d[x].son[0]=++siz;
    134         build(d[x].son[0],1,(kiz+1)>>1);
    135         d[x].son[1]=++siz;
    136         build(d[x].son[1],((kiz+1)>>1)+1,kiz);
    137     }
    138 }
    139 void build(ll x,ll l,ll r)
    140 {
    141     d[x].l=l;d[x].r=r;d[x].fl=1;
    142     if(l!=r)
    143     {
    144         d[x].son[0]=++siz;
    145         build(siz,l,(l+r)>>1);
    146         d[x].son[1]=++siz;
    147         build(siz,((l+r)>>1)+1,r);
    148     }
    149 }
    bzoj3932
  • 相关阅读:
    [ html canvas getImageData Object.data.length ] canvas绘图属性 getImageData Object.data.length 属性讲解
    [ html canvas 模仿支付宝刮刮卡效果 ] canvas绘图属性 模仿支付宝刮刮卡效果实例演示
    [ javascript html Dom image 对象事件加载方式 ] 对象事件加载方式
    [ javascript New Image() ] New Image() 对象讲解
    Django安装及环境配置
    python使用opencv实现人脸识别系统
    redis 操作常用命令
    关于Python获取SQLSERVER数据库中文显示乱码问题
    Topshelf创建windows服务初探
    Js获取ip地址
  • 原文地址:https://www.cnblogs.com/Zn-H/p/6492891.html
Copyright © 2020-2023  润新知