• 【主席树】BZOJ3932-[CQOI2015]任务查询系统


    【题目大意】

    超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi。询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少。特别的,如果Ki大于第Xi秒正在运行的任务总数,则直接回答第Xi秒正在运行的任务优先级之和。上述所有参数均为整数,时间的范围在1到n之间(包含1和n)。

    【思路】

    主席树。在Si秒开始,在Ei秒结束,相当于在Si秒加一,在Ei秒减一的前缀和。

    把优先级看作数值,把时间看作T树下标。将优先级离散化后,按照时间排序,记录三元组(time,p,delta),描述时间,优先级及变化量(+1或-1),对于同一个时间,如果当前时间第一次出现,在T[time-1]的基础上更新,否则在T[time]的基础上更新。注意,中间空白的时间段,T[time]=T[time-1]。

    【错误点】

    query返回条件,但l==r时,不可以直接返回sum,而是sum/size*k。

    因为我当前的size可能大于k。

      1 //时刻->下标
      2 //优先级->数值 
      3 #include<iostream>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<vector> 
      8 #define lson l,m
      9 #define rson m+1,r
     10 using namespace std;
     11 const int MAXN=100000+50;
     12 typedef long long ll;
     13 struct node
     14 {
     15     int time,p,delta;
     16 
     17 }a[MAXN*2];
     18 bool cmp(node x,node y)
     19 {
     20     return (x.time<y.time);
     21 }
     22 int m,n,tot,d;
     23 int hash[MAXN],T[MAXN],size[MAXN<<7],L[MAXN<<7],R[MAXN<<7];
     24 ll sum[MAXN<<7];
     25 
     26 int build(int l,int r)
     27 {
     28     int rt=++tot;
     29     sum[rt]=size[rt]=0;
     30     if (l<r)
     31     {
     32         int m=(l+r)>>1;
     33         L[rt]=build(lson);
     34         R[rt]=build(rson);
     35     }
     36     return rt;
     37 }
     38 
     39 int update(int pre,int l,int r,int x,int delta)
     40 {
     41     int rt=++tot;
     42     L[rt]=L[pre],R[rt]=R[pre]; 
     43     sum[rt]=sum[pre]+(ll)delta*hash[x]; // sum  优先级的和:例如两个优先级为3的人物,那么sum=6,而size=2 
     44     size[rt]=size[pre]+delta;            // size 优先级个数的和:例如两个优先级为3的人物,那么sum=6,而size=2 
     45     if (l!=r)
     46     {
     47         int m=(l+r)>>1;
     48         if (x<=m) L[rt]=update(L[rt],lson,x,delta);
     49             else R[rt]=update(R[rt],rson,x,delta);
     50     }
     51     return rt;
     52 }
     53 
     54 
     55 ll query(int rt,int l,int r,ll k)
     56 {
     57     int nowsize=size[rt];
     58     if (k>=nowsize) return (sum[rt]);
     59     if (l==r) return (sum[rt]/size[rt]*k);
     60     //当l==r时,当前值可能有多个,且总数大于k,所以只需返回k*当前值即可 
     61     int num=size[L[rt]];
     62     ll ret;
     63     int m=(l+r)>>1;
     64     if(num>=k)
     65         ret=query(L[rt], lson, k);
     66     else
     67         ret=sum[L[rt]]+query(R[rt],rson, k-num);
     68     return ret;
     69 }
     70 
     71 void init()
     72 {
     73     tot=0;
     74     scanf("%d%d",&m,&n);
     75     for (int i=1;i<=m;i++)
     76     {
     77         int s,e,p;
     78         scanf("%d%d%d",&s,&e,&p);
     79         a[2*i-1]=(node){s,p,1};
     80         a[2*i]=(node){e+1,p,-1};
     81         hash[i]=p;
     82     }
     83     sort(hash+1,hash+m+1);
     84     m=m*2;
     85     sort(a+1,a+m+1,cmp);
     86     
     87     d=unique(hash+1,hash+(m>>1)+1)-(hash+1);
     88     T[0]=build(1,d);
     89     for (int i=1;i<=m;i++)
     90     {
     91         int x=lower_bound(hash+1,hash+d+1,a[i].p)-hash;
     92         int t=a[i].time;
     93         if (i==1 || t!=a[i-1].time)
     94         {
     95             if (i!=1) for (int j=a[i-1].time+1;j<t;j++) T[j]=T[j-1];
     96             T[t]=update(T[t-1],1,d,x,a[i].delta);
     97         }
     98         else T[t]=update(T[t],1,d,x,a[i].delta);
     99     }
    100 }
    101 
    102 void solve()
    103 {
    104     int pre=1;
    105     for (int i=0;i<n;i++)
    106     {
    107         ll x,a,b,c;
    108         scanf("%lld%lld%lld%lld",&x,&a,&b,&c);
    109         ll k=1+(ll)(a*pre+b)%c;
    110         ll ans=query(T[x],1,d,k); 
    111         printf("%lld
    ",ans);
    112         pre=ans;
    113     }
    114 }
    115 
    116 int main()
    117 {
    118     //freopen("cqoi15_query.in","r",stdin);
    119     //freopen("cqoi15_query.out","w",stdout);
    120     init();
    121     solve(); 
    122     return 0;
    123 } 
  • 相关阅读:
    关于VS下的应用程序出现0xc000007b的问题以及OpenCV相关的0xc000007b问题
    彻底解决DZ大附件上传问题
    基于Red5的视频直播平台
    .htaccess重写URL讲解
    了解Linux实时内核
    Linux操作系统实时性分析
    5分钟教程:如何通过UART获得root权限
    记一次有惊无险的Linux数据恢复过程
    11款最棒的Linux数据恢复工具
    Xamarin.Android开发实践(六)
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5769531.html
Copyright © 2020-2023  润新知