zoukankan      html  css  js  c++  java
  • 主席树||可持久化线段树||离散化||[CQOI2015]任务查询系统||BZOJ 3932||Luogu P3168

    题目: [CQOI2015]任务查询系统

    题解:

    是一道很经典的题目。大体思路是抓优先级来当下标做主席树,用时刻作为主席树的版本。然而优先级范围到1e7去了,就离散化一遍。然后把每个事件的开始(s)、结束(e)(e记得+1,因为一个事件是第e+1时刻结束的)时间点抓出来排序一遍,按时刻从早到晚维护主席树。差不多就是这样。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define ll long long
     6 #define max(a,b) ((a)>(b)?(a):(b))
     7 #define min(a,b) ((a)<(b)?(a):(b))
     8 using namespace std;
     9 const int maxn=100000+50,maxm=maxn,maxnum_p=maxm,maxnum_b=maxm<<1;
    10 int N,M,cnt_p=0,num_b=0,num_treenode,root[maxnum_b],X,A,B,C,belong_root[maxn];
    11 ll Pre=1,belong[maxm],K;
    12 struct _A{int p,s,e,hp;}a[maxm];
    13 bool cmp1(const _A&c,const _A&d){return(c.p<d.p);}
    14 struct _B{int p,o,data;}b[maxm<<1];//b数组负责记录把每个时间点都拆出来后的数据 ,data记录时间点,o是时间点的类型 
    15 bool cmp2(const _B&c,const _B&d){return(c.data<d.data);}
    16 struct Tree{int l,r,ls,rs,cnt;ll sum;}t[(maxnum_p<<2)+maxnum_b*18];
    17 void Build(int x,int l,int r){
    18     t[x].l=l;t[x].r=r;int mid=(l+r)>>1;
    19     if(l==r)return;
    20     Build(t[x].ls=++num_treenode,l,mid);Build(t[x].rs=++num_treenode,mid+1,r);
    21     return;
    22 }
    23 void Update(int u,int x,int p,int o){
    24     int l=t[u].l,r=t[u].r,mid=(l+r)>>1;
    25     t[x].l=l;t[x].r=r;
    26     if(l==r&&l==p){
    27         if(o==1){t[x].cnt=t[u].cnt+1; t[x].sum=t[u].sum+belong[p];}
    28             else{t[x].cnt=t[u].cnt-1; t[x].sum=t[u].sum-belong[p];}
    29         return;
    30     }
    31     if(p<=mid){t[x].rs=t[u].rs; Update(t[u].ls,t[x].ls=++num_treenode,p,o);}
    32           else{t[x].ls=t[u].ls; Update(t[u].rs,t[x].rs=++num_treenode,p,o);}
    33     t[x].cnt=t[t[x].ls].cnt+t[t[x].rs].cnt;
    34     t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum;
    35     return;
    36 }
    37 ll Query(int x,ll k){
    38     if(k==0)return 0;
    39     if(k>=t[x].cnt)return t[x].sum;
    40     int l=t[x].l,r=t[x].r,ls=t[x].ls,rs=t[x].rs;
    41     if(l==r)return (k*belong[l]);
    42     if(t[ls].cnt>=k)return Query(ls,k);
    43     else return (t[ls].sum+Query(rs,k-t[ls].cnt));
    44 }
    45 int main(){
    46     scanf("%d%d",&M,&N);
    47     for(int i=1;i<=M;i++)scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].p),a[i].e++;
    48     sort(a+1,a+M+1,cmp1);
    49     for(int i=1;i<=M;i++)
    50         if(a[i].p!=a[i-1].p)belong[a[i].hp=++cnt_p]=a[i].p;else a[i].hp=cnt_p;
    51     for(int i=1;i<=M;i++){
    52         b[++num_b].data=a[i].s;b[num_b].o=1;b[num_b].p=a[i].hp;
    53         b[++num_b].data=a[i].e;b[num_b].o=2;b[num_b].p=a[i].hp;
    54     }
    55     Build(root[0]=++num_treenode,1,cnt_p);
    56     sort(b+1,b+num_b+1,cmp2);
    57     for(int i=1;i<=num_b;i++){
    58         int v=b[i].data,o=b[i].o,p=b[i].p;
    59         Update(root[i-1],root[i]=++num_treenode,p,o);
    60         if(v!=b[i+1].data)belong_root[v]=i; 
    61     }
    62     for(int i=1;i<=N;i++)if(belong_root[i]==0)belong_root[i]=belong_root[i-1];
    63     while(N--){
    64         scanf("%d%d%d%d",&X,&A,&B,&C);
    65         K=1+(Pre*A+B)%C;
    66         Pre=Query(root[belong_root[X]],K);
    67         printf("%lld
    ",Pre);
    68     }
    69     return 0;
    70 }

    By:AlenaNuna

  • 相关阅读:
    工厂模式
    dubbo
    WebSocket WebService
    消息中间
    原型模式
    ApiPost Apifox
    Future 的使用与源码解析
    JUC 线程池的使用与源码解析
    ReentrantLock 源码解析
    CountDownLatch 的使用与源码解析
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/10415593.html
Copyright © 2011-2022 走看看