zoukankan      html  css  js  c++  java
  • 分块总结

    这几天学习了分块和莫队

    “分块和莫队都是优雅的暴力”--数据结构带师wsk_1202

    确实,分块的主要思想就是将两端暴力处理,中间拿tag标记或其他途径维护一下,将修改与询问的时间复杂度分摊,达到(O(nsqrt{n}))的时间复杂度

    这一个题库里涉及了很多分块的基本操作和用法,有时间可以多看一看

    放一个分块入门1的代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,a[50003],tag[50003],pos[50003],typ,m,l,r,c;
    void add(int l1,int r1,int num)
    {
    	for(int i=l1;i<=min(r1,pos[l1]*m);i++) //枚举左边界
    		a[i]+=num;
    	if(pos[l1]!=pos[r1])
    		for(int i=(pos[r1]-1)*m+1;i<=r1;i++) //枚举右边界
    			a[i]+=num;
    	for(int i=pos[l1]+1;i<=pos[r1]-1;i++) //枚举中间的整块
    		tag[i]+=num;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	m=sqrt(n); //还可以取pow(n,0.33)或pow(n,0.4)等等
    	for(int i=1;i<=n;i++)
    		pos[i]=(i-1)/m+1; //统计每个元素所在的块
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%d%d%d",&typ,&l,&r,&c);
    		if(typ==0)
    			add(l,r,c);
    		else
    			cout<<a[r]+tag[pos[r]]<<endl;
    	}
    	return 0;
    }
    

    分块的代码是不是看起来就很暴力

    在洛谷上写分块的时候写到了一个题,这道题巧妙地运用了分块的思想(貌似是根号分治),把原本预处理(O(n^2)),询问(O(1)),均摊一下,变成了预处理(O(nsqrt{n})),询问(O(nsqrt{n})),从而实现了均摊复杂度,是一种很巧妙地思想

  • 相关阅读:
    C语言编程题
    boost-使用说明
    CButton控件
    sprintf()与sscanf()
    MFC中的几个虚函数
    CProgressCtrl进度条控件实现进度滚动效果
    移动窗口和根据条件查找指定窗口
    VC播放mp3的方法
    CEdit控件[转]
    关于鼠标的一些操作
  • 原文地址:https://www.cnblogs.com/dzice/p/12203612.html
Copyright © 2011-2022 走看看