zoukankan      html  css  js  c++  java
  • 【洛谷3793】由乃救爷爷(分块)

    点此看题面

    • 给定一个长度为(n)的序列,(m)次询问区间最大值。
    • (n,mle2 imes10^7),数据随机

    分块

    考虑分块,维护(Mx_{i,j})表示第(isim j)个块的最大值,(pre_i)表示(i)在所在块中的前缀最大值,(suf_i)表示(i)在所在块中的后缀最大值。

    那么一个询问就可以拆成一个后缀+一段完整块+一个前缀。

    然而问题来了——如何处理块内询问?

    考虑一次询问两个端点相同的概率是(O(frac1{sqrt n}))的,因此我们完全可以直接暴力。

    代码:(O(n))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 20000000
    #define S 10000
    using namespace std;
    int n,m,s,a[N+5],sz,bl[N+5],Mx[S+5][S+5],pre[N+5],suf[N+5];
    namespace R//随机数生成器
    {
    	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) {z1=x,z2=(~x)^0x233333333U,z3=x^0x1234598766U,z4=(~x)+51;}
    }
    int read() {int a=R::rand_()&32767,b=R::rand_()&32767;return a*32768+b;}
    int main()
    {
    	RI i,j;for(scanf("%d%d%d",&n,&m,&s),R::srand(s),i=1;i<=n;++i) a[i]=read();
    	for(i=1;i<=n;++i) bl[i]=(i-1)/S+1,Mx[bl[i]][bl[i]]=max(Mx[bl[i]][bl[i]],a[i]);
    	for(i=1;i<=bl[n];++i) for(j=i+1;j<=bl[n];++j) Mx[i][j]=max(Mx[i][j-1],Mx[j][j]);//第i~j个块的最大值
    	for(i=1;i<=n;++i) pre[i]=max(bl[i-1]^bl[i]?0:pre[i-1],a[i]);//i所在块的前缀最大值
    	for(i=n;i>=1;--i) suf[i]=max(bl[i+1]^bl[i]?0:suf[i+1],a[i]);//i所在块的后缀最大值
    	RI l,r,t;unsigned long long ans=0;W(m--)
    	{
    		(l=read()%n+1)>(r=read()%n+1)&&(swap(l,r),0);
    		if(bl[l]==bl[r]) {for(t=0,i=l;i<=r;++i) t=max(t,a[i]);ans+=t;}//同块直接暴力
    		else ans+=max(Mx[bl[l]+1][bl[r]-1],max(suf[l],pre[r]));//不同块利用维护出的信息求解
    	}return printf("%llu
    ",ans),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    索引结构
    云时代基础设置自动化管理利器: Chef
    软件Scrum
    选择置换+败者树搞定外部排序
    selenium webdriver (python)2
    [置顶] javascript-基于对象or面向对象?
    4.7 阻止对某几列插入
    mysql数据损坏修复方法
    阿里云挂载数据盘
    Delphi 使用双缓冲解决图片切换时的闪烁问题 good
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu3793.html
Copyright © 2011-2022 走看看