传送门


因为昨天写暴力写挂在UOJ上用快排惨遭卡常,所以今天准备写一个卡常题消遣消遣,然后时间又垫底了QAQ

这道题显然需要支持一个\(O(N)\)预处理\(O(1)\)查询的ST表,显然普通的ST表是做不到的,因为预处理的时间太长了

于是分块优化掉ST表的预处理

约定\(L_i,R_i\)表示第\(i\)个块的左端点和右端点,\(be_i\)表示第\(i\)个数所在的块

对于每一个位置\(i\)预处理\(L_{be_i}\)到\(i\)的所有数的最大值\(lmax_i\)以及\(i\)到\(R_{be_i}\)的所有数的最大值\(rmax_i\);预处理块最大值的ST表

对于一个询问\((l,r)\),如果\(be_i \neq be_r\)查询\(rmax_l , lmax_r\)以及\(be_l+1\)到\(be_r-1\)的所有块的最大值,三者取\(max\);如果\(be_l = be_r\)就暴力

考虑复杂度,设块长为\(S\),预处理复杂度瓶颈为ST表复杂度\(O(\frac{N}{S}log\frac{N}{S})\);询问复杂度上,如果\(be_l \neq be_r\)为\(O(1)\),否则为\(O(S)\)。因为数据随机,出现\(be_l = be_r\)的概率为\(\frac{S}{N}\),所以最坏查询复杂度为\(O(S^2)\),总复杂度为\(O(\frac{N}{S}log\frac{N}{S} + S^2)\)

差不多当\(S = \sqrt[3]{NlogN}\)的时候有最优复杂度,但是因为数据随机所以块长开大一点也没关系

然后可能需要一些奇怪的常数优化比如把max define掉之类的

#include<bits/stdc++.h>
using namespace std;

namespace GenHelper
{
    unsigned z1,z2,z3,z4,b;
    unsigned rand_()
    {
    b=((z1<<6)^z1)>>13;
    z1=((z1&4294967294U)<<18)^b;
    b=((z2<<2)^z2)>>27;
    z2=((z2&4294967288U)<<2)^b;
    b=((z3<<13)^z3)>>21;
    z3=((z3&4294967280U)<<7)^b;
    b=((z4<<3)^z4)>>12;
    z4=((z4&4294967168U)<<13)^b;
    return (z1^z2^z3^z4);
    }
}
void srand(unsigned x)
{
    using namespace GenHelper;
    z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;
}
int read()
{
    using namespace GenHelper;
    int a=rand_()&32767;
    int b=rand_()&32767;
    return a*32768+b;
}

const int MAXN = 2e7 + 7;
unsigned int arr[MAXN] , maxN1[MAXN] , maxN2[MAXN] , ST[15][26000] , logg2[26000];
unsigned int N , M , S , T , cnt;

#define cmp(a , b) ((a) > (b) ? (a) : (b))

inline unsigned int qST(int x , int y){
    if(x > y)
        return 0;
    int t = logg2[y - x + 1];
    return cmp(ST[t][x] , ST[t][y - (1 << t) + 1]);
}

int main(){
    cin >> N >> M >> S;
    srand(S);
    T = pow(N * log2(N) , 1.0/3);
    cnt = N / T + (N % T ? 1 : 0);
    for(int i = 1 ; i <= N ; ++i){
        arr[i] = read();
        maxN2[i] = arr[i];
        if(i % T != 1)
            maxN2[i] = cmp(maxN2[i] , maxN2[i - 1]);
    }
    for(int i = N ; i ; --i){
        maxN1[i] = arr[i];
        if(i % T)
            maxN1[i] = cmp(maxN1[i] , maxN1[i + 1]);
        if(i % T == 1)
            ST[0][i / T + 1] = maxN1[i];
    }
    for(int i = 2 ; i <= cnt ; ++i)
        logg2[i] = logg2[i >> 1] + 1;
    for(int i = 1 ; 1 << i <= cnt ; ++i)
        for(int j = 1 ; j + (1 << i) - 1 <= cnt ; ++j)
            ST[i][j] = cmp(ST[i - 1][j] , ST[i - 1][j + (1 << (i - 1))]);
    unsigned long long sum = 0;
    while(M--){
        int l = read() % N + 1 , r = read() % N + 1;
        if(l > r)
            swap(l , r);
        if((l - 1) / T == (r - 1) / T){
            unsigned int ans = 0;
            for(int i = l ; i <= r ; ++i)
                ans = cmp(ans , arr[i]);
            sum += ans;
        }
        else
            sum += cmp(cmp(maxN1[l] , maxN2[r]) , qST((l - 1) / T + 2 , (r - 1) / T));
    }
    cout << sum;
    return 0;
}

Luogu3793 由乃救爷爷 分块、ST表的更多相关文章

  1. P3793-由乃救爷爷【分块,ST表】

    正题 题目链接:https://www.luogu.com.cn/problem/P3793 题目大意 给出\(n\)个数字的一个序列\(m\)次询问区间最大值 保证数据随机 \(1\leq n,m\ ...

  2. 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块

    题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...

  3. Luogu 3793 由乃救爷爷

    \(\verb|Luogu 3793 由乃救爷爷|\) rmq,数据随机 \(n,\ m\leq 2\times10^7\) lxl ST表 分块,大小设为 \(x\) 预处理每个块两端到块内每个点的 ...

  4. [bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)

    Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...

  5. [BZOJ1012] [JSOI2008] 最大数maxnumber (ST表)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  6. CF1039E Summer Oenothera Exhibition 贪心、根号分治、倍增、ST表

    传送门 感谢这一篇博客的指导(Orzwxh) $PS$:默认数组下标为$1$到$N$ 首先很明显的贪心:每一次都选择尽可能长的区间 不妨设$d_i$表示在取当前$K$的情况下,左端点为$i$的所有满足 ...

  7. CF1039E Summer Oenothera Exhibition 根号分治,LCT,ST表

    CF1039E Summer Oenothera Exhibition LG传送门 根号分治好题. 可以先看我的根号分治总结. 题意就是给出长度为\(n\)的区间和\(q\)组询问以及一个\(w\), ...

  8. 【笔记】自学ST表笔记

    自学ST表笔记 说实话原先QBXT学的ST表忘的差不多了吧...... 我重新自学巩固一下(回忆一下) 顺便把原先一些思想来源的原博发上来 一.ST表简介 ST表,建表时间\(O(n\cdot log ...

  9. [洛谷P3793]由乃救爷爷

    题目大意:有$n(n\leqslant2\times10^7)$个数,$m(m\leqslant2\times10^7)$个询问,每次询问问区间$[l,r]$中的最大值.保证数据随机 题解:分块,处理 ...

随机推荐

  1. 【读书笔记】iOS-Apple的移动设备硬件

    本书中有一个关键观点是:“硬件并不是特别重要,用户体验才是真正的杀手级应用.“尽管如此,多了解一些你使用的硬件的相关知识,对于整个项目来说是必备的,而对于设计和开发高质量的作品来说敢是不可或缺的. 人 ...

  2. Related concepts of testing

    根据是否知道源代码测试可以分为黑盒和白盒. 黑盒:功能测试. 白盒:知道源代码,要写测试代码. 根据测试的粒度. 方法测试: 单元测试: 集成测试: 系统测试: 根据测试的暴力程度. 压力测试:谷歌工 ...

  3. 【Java入门提高篇】Day30 Java容器类详解(十二)TreeMap详解

    今天来看看Map家族的另一名大将——TreeMap.前面已经介绍过Map家族的两名大将,分别是HashMap,LinkedHashMap.HashMap可以高效查找和存储元素,LinkedHashMa ...

  4. Tensorflow激活函数

    注意: 1.大多情况下使用Relu激活函数这种激活函数计算快,且在梯度下降中不会卡在plateaus(平稳段),对于大的输入,也不会饱和. 2.logistic function和hyperbloic ...

  5. 【公众号系列】SAP S/4 HANA的移动平均价

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[公众号系列]SAP S/4 HANA的移动平均 ...

  6. 万能Makefile,前戏做足项目做起来才顺畅。

    # 获取要编译的源码 SRC :=$(wildcard *.cpp) OBJ :=$(patsubst %.cpp,%.o,$(SRC)) # 编译参数 CC :=g++ STD :=-std=c++ ...

  7. Requests 校花网图片爬取

    纪念我们闹过的矛盾,只想平淡如水 import requestsimport reurl = 'http://www.xiaohuar.com/list-1-%s.html'for i in rang ...

  8. SAP系统产品历史与分类

    SAP R/1---实时会计辅助财务的系统,最早叫RF系统.由原来批处理系统(数据输入后,由服务器在特定的时间分批处理).创造性的变为输入马上由计算机处理. SAP R/2—创造性的使用“basis” ...

  9. 二: python基础数据类型(int,

    一.什么是数据类型?2018-12-20   20:57:3õ # (3) num = 0 while num < 10: num += 1 if num == 7: num += 1 # 7执 ...

  10. python基础 - 字符串作

    split(sep=None, maxsplip=-1) 从左到右 sep 指定分隔字符串,缺省情况下空白字符串,指定的字符串会被切掉 maxsplit 指定分隔次数,-1 表示遍历 rsplit(s ...