zoukankan      html  css  js  c++  java
  • 51nod1624 取余最长路 前缀和 + set

    由于只有3行,因此只会会换行2次,假设$x, y$分别为这两次的换行点

    那么答案为$S[1][x] +S[2][y] - S[2][x - 1] + S[3][n] - S[3][y - 1]$

    其中,$S[i]$表示第$i$行的前缀和

    令$a[x] = S[1][x] - S[2][x - 1], b[y] = S[2][y] - S[3][y - 1]$

    考虑枚举$x$,那么问题转化为询问在一堆数中求一个数$k$使得$v (= a[x] + S[3][n]) + k ;mod;p$最大

    分两种情况考虑,第一种$v + k in [v, mod - 1]$,那么$k in [0, mod - k - 1]$,并且$k$越大越好

    第二种不如第一种好,但有可能不得不选,$v + k in [1, v - 1]$,同样时$k$越大越好

    也就是说,需要一种支持插入,查询前驱和最大值的数据结构,$set$就可以

    注:倒叙枚举$x$,可以做到不删除

    复杂度$O(n log n)$

    #include <set>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    extern inline char gc() {
        static char RR[23456], *S = RR + 23333, *T = RR + 23333;
        if(S == T) fread(RR, 1, 23333, stdin), S = RR;
        return *S ++;
    }
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    #define ll long long
    #define ri register int
    #define sid 200050
    
    int n, ans, mod;
    int s[4][sid], a[sid], b[sid];
    
    set <int> ex;
    
    int main() {
        n = read(); mod = read();
        for(ri i = 1; i <= 3; i ++)
        for(ri j = 1; j <= n; j ++)
        s[i][j] = (s[i][j - 1] + read()) % mod;
    
        for(ri i = 1; i <= n; i ++) a[i] = (s[1][i] - s[2][i - 1] + mod) % mod;
        for(ri i = 1; i <= n; i ++) b[i] = (s[2][i] - s[3][i - 1] + mod) % mod;
        
        int der = s[3][n]; ex.insert(1);
        for(ri i = n; i >= 1; i --) {
            ex.insert(-b[i]);
            int v = (der + a[i]) % mod;
            int p = *ex.lower_bound(-(mod - 1 - v));;
            if(p == 1) ans = max(ans, (v - *(++ ex.begin())) % mod);
            else ans = max(ans, v + -p);
        }
    
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    Ubuntu中的Gif动画录制工具
    NDT(Normal Distributions Transform)算法原理与公式推导
    激光数据匹配(MATLAB Robotics System Toolbox)
    使用正态分布变换(Normal Distributions Transform)进行点云配准
    微软Xbox One无线手柄控制机器人
    SICK LMS111激光雷达的使用
    SICK TiM561激光雷达的使用
    JAVA操作Hbase
    shell date 命令整理
    ArrayList排序
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9556662.html
Copyright © 2011-2022 走看看