zoukankan      html  css  js  c++  java
  • [洛谷P3793]由乃救爷爷

    目大意:有$n(nleqslant2 imes10^7)$个数,$m(mleqslant2 imes10^7)$个询问,每次询问问区间$[l,r]$中的最大值。保证数据随机

    题解:分块,处理出每个元素块中前缀最大值和后缀最大值,并且处理出整块的区间最大值(用$ST$表),然后似乎就可以$O(1)$求区间最大值啦!

    然而发现若$l,r$在同一块中就会出锅,那就直接暴力查询(数据随机)

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    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);
        }
    }
    unsigned RAND;
    void srand(unsigned x)
    {using namespace GenHelper;
    z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;}
    int read()
    {
        using namespace GenHelper;
    	static int a, b;
        a=rand_()&32767;
        b=rand_()&32767;
        return a << 15 | b;
    }
    
    #define maxn 20000010
    #define M 13
    const int BSZ = 4480, BNUM = maxn / BSZ + 10;
    int n, m, s[maxn];
    unsigned long long ans;
    
    int Lmax[maxn], Rmax[maxn];
    int L[BNUM], R[BNUM], bel[maxn];
    
    int ST[M + 1][BNUM], LG[BNUM];
    inline int query(int l, int r) {
    	if (l >= r) return 0;
    	static int t; t = LG[r - l];
    	return std::max(ST[t][l], ST[t][r - (1 << t)]);
    }
    
    int main() {
    	scanf("%d%d%u", &n, &m, &RAND); srand(RAND);
    	for (int i = 1; i <= n; ++i) {
    		s[i] = read();
    		bel[i] = i / BSZ + 1;
    	}
    
    	const int B = bel[n];
    	LG[0] = -1; for (int i = 1; i <= B; ++i) LG[i] = LG[i >> 1] + 1;
    	for (int i = 1; i <= B; ++i) {
    		L[i] = (i - 1) * BSZ;
    		R[i] = L[i] + BSZ - 1;
    	}
    	L[1] = 1, R[B] = n;
    	for (int i = 1, now = 1, last = 0; i <= n; ++i) {
    		Lmax[i] = last = std::max(s[i], last);
    		if (i >= R[now]) ST[0][now] = Lmax[i], last = 0, ++now;
    	}
    	for (int i = n, now = B, last = 0; i; --i) {
    		Rmax[i] = last = std::max(s[i], last);
    		if (i <= L[now]) last = 0, --now;
    	}
    	for (int i = 1, pw = 1; i <= M; ++i, pw <<= 1) {
    		for (int j = 1; j <= B; ++j) ST[i][j] = std::max(ST[i - 1][j], ST[i - 1][std::min(j + pw, B)]);
    	}
    
    	while (m --> 0) {
    		int l = read() % n + 1, r = read() % n + 1;
    		if (l > r) std::swap(l, r);
    		const int lb = bel[l], rb = bel[r];
    		if (lb != rb) {
    			ans += std::max(std::max(Rmax[l], Lmax[r]), query(lb + 1, rb));
    		} else {
    			static int res; res = 0;
    			for (int i = l; i <= r; ++i) res = std::max(res, s[i]);
    			ans += res;
    		}
    	}
    	printf("%llu
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    AsWing入门教程 1.4 在面板中显示信息
    AsWing 入门教程 1.3 给框架定位
    LocalConnection AS2与AS3通信说明
    Tuscany SCA与Spring、Hibernate整合之简洁方法
    《spring2.0技术手册》读书笔记九spring与hibernate整合DAO的书写,HibernateTemplate解析
    求n个骰子各点数和出现的概率动态规划
    oracle常用函数总结
    Hadoop概要MapReduce的认识
    HDFS的使用及编程
    Apache Hadoop的安装与配置
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10228757.html
Copyright © 2011-2022 走看看