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

  • 相关阅读:
    Uva 10779 collector's problem
    poj 2728 最优比率树(最小生成树问题)
    LA 3126 二分图匹配 最小路径覆盖
    poj 1149 最大流构图
    Step By Step(Java XML篇)
    Step By Step(Java 输入输出篇)
    Step By Step(Java 集合篇)
    Step By Step(Java 线程篇)
    Step By Step(Java 反射篇)
    Step By Step(Java 国际化篇)
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/10415593.html
Copyright © 2011-2022 走看看