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

    P3168 [CQOI2015]任务查询系统


    题意

    给出若干带有权值的区间, 每个区间可能相交或相离, 每个区间有三个属性(Si, Ei, Pi), 分别表示左端点,右端点,权值,其中端点范围属于[1, N]内;
    随后有N条询问, 给出Xi, Ki, 令涉及到[1, Xi]区间中排名第Ki小的区间为A, 输出排名属于[1, K]时间点小于等于A的所有区间的权值和


    Solution

    • 将区间中权值的添加与删去用差分操作来表示
    • 离散化端点, 权值
    • 按时间线排序的差分操作建立主席树
    • 于每条询问, 输出查询结果即可

    需要注意的点

    1. 主席树的空间为 logNNlogN * N(最好多开1倍…)
    2. 注意离散化数值与权值之间不要混用

    Code

    #include<bits/stdc++.h>
    #define reg register
    
    const int maxn = 2e5 + 10;
    
    int M;
    int N;
    int Len;
    int cnt;
    int Q_num;
    int node_cnt;
    int B[maxn<<2];
    int rot[maxn*10];
    int Apos[maxn<<2];
    
    struct Cf{ int pos, val, opt; } A[maxn<<2];
    
    struct Task{ int S, E, P; } ts[maxn<<2];
    
    struct Node{ int lt, rt, val_sum, sum, cnt; } T[maxn*18]; 
    
    bool cmp(Cf a, Cf b){ return a.pos < b.pos; }
    
    void Add_node(int &now, int last, int l, int r, int val, int opt, int v){
            T[now = ++ node_cnt] = T[last];
            T[now].val_sum += opt * v;
            T[now].sum += opt;
            if(l == r) return ;
            int mid = l+r >> 1;
            if(val <= mid) Add_node(T[now].lt, T[last].lt, l, mid, val, opt, v);
            else Add_node(T[now].rt, T[last].rt, mid+1, r, val, opt, v);
    }
    
    int Query(int rot, int k){
            int lt = T[rot].lt, rt = T[rot].rt;
            if(!lt && !rt) return T[rot].val_sum/T[rot].sum * k;
            int lsum = T[lt].sum, rsum = T[rt].sum;
            if(lsum >= k) return Query(lt, k);
            return T[lt].val_sum + Query(rt, k - lsum);
    }
    
    int main(){
            scanf("%d%d", &M, &Q_num);
            for(reg int i = 1; i <= M; i ++){
                    scanf("%d%d%d", &ts[i].S, &ts[i].E, &ts[i].P);
                    A[++ cnt] = (Cf){ ts[i].S, ts[i].P, 1 };
                    A[++ cnt] = (Cf){ ts[i].E+1, ts[i].P, -1 }; // ts[i].E "+1"
                    B[++ N] = ts[i].P;
            }
            std::sort(A+1, A+cnt+1, cmp);
            std::sort(B+1, B+N+1);
            Len = std::unique(B+1, B+N+1) - B-1;
            for(reg int i = 1; i <= cnt; i ++){
                    A[i].val = std::lower_bound(B+1, B+Len+1, A[i].val) - B;
                    Apos[i] = A[i].pos;
            }
            for(reg int i = 1; i <= cnt; i ++) Add_node(rot[i], rot[i-1], 1, Len, A[i].val, A[i].opt, B[A[i].val]);
            int Pre_ans = 1;
            for(reg int i = 1; i <= Q_num; i ++){
                    int Xi, Ai, Bi, Ci;
                    scanf("%d%d%d%d", &Xi, &Ai, &Bi, &Ci);
                    int Ki = 1 + (1ll*Ai*Pre_ans + Bi) % Ci;
                    int pos = std::upper_bound(Apos+1, Apos+cnt+1, Xi) - Apos-1;
                    if(Ki >= T[rot[pos]].sum) printf("%d
    ", Pre_ans=T[rot[pos]].val_sum);
                    else printf("%d
    ", Pre_ans=Query(rot[pos], Ki));
            }
            return 0;
    }
    //Do not confuse the 离散 and the origin value !
    //Do remember the root[]'s size need to be large as the T[] !
    //All arrays connected to Cf[] need to be large !
    
  • 相关阅读:
    第一章 概述
    Angular-----代码风格指南!!!(很重要)
    Angular中innerHTML标签的样式不起作用详解
    maven入门
    vue解惑之v-on(事件监听指令)
    vue解惑之slot(插槽)
    js中关于constructor与prototype的理解
    Angular--AOT和JIT两种编译方式带来的改变
    ArcGIS API for JavaScript小白入门
    ionic项目使用Google FCM插件和Google maps插件打包android报错冲突问题
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822691.html
Copyright © 2011-2022 走看看