博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分块学习
阅读量:4973 次
发布时间:2019-06-12

本文共 2619 字,大约阅读时间需要 8 分钟。

分块是一种非常常用的技巧,他功能非常强大;然而相对的,它的时间复杂度较高,这也是它的缺陷。

设定每块大小为根号n,这样就把序列分为了n/根号n块

对于每一块,整体处理,不能构成一块的,暴力处理

 

代码:

for(int i=1;i<=n;i++)    {        a[i]=read();belong[i]=(i-1)/t+1;        sum[belong[i]]+=a[i];    }

这样就完成了分块 例如10个数,belong[i]分别为 1 1 1 2 2 2 3 3 3 4

 

修改或查询时分三段区间

1. L~min(belong[L],R),闭区间。

2. belong[L]+1~belong[R],半开半闭区间。

3.(belong[R]-1)*t+1~t,闭区间。

这样就OK啦 例如区间求和

代码:

int query(int x,int y){    ans=0;    for(int i=x;i<=min(y,belong[x]*t);i++) ans+=a[i];    for(int i=belong[x]+1;i

 

以下3题练练手

T1  线段树练习  

#include
#include
#include
#include
#define N 100001using namespace std;int n,m,x,y,z,t,ans,a[N],belong[N],sum[N];inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}int query(int x,int y){ ans=0; for(int i=x;i<=min(y,belong[x]*t);i++) ans+=a[i]; for(int i=belong[x]+1;i
单点修改,区间查询

T2  线段树练习2

#include
#include
#include
#include
#define N 100001using namespace std;int n,m,q,x,y,z,t,ans,a[N],belong[N],tot[N];inline int read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}int main(){ n=read();t=sqrt(n); for(int i=1;i<=n;i++) { a[i]=read(); belong[i]=(i-1)/t+1; } m=read(); for(int i=1;i<=m;i++) { x=read(); if(x==1) { y=read();z=read();q=read(); for(int i=y;i<=min(z,belong[y]*t);i++) a[i]+=q; for(int i=belong[y]+1;i
单点查询,区间修改

T3  线段树练习3 

#include
#include
#include
#include
#define N 200001using namespace std;long long n,m,x,y,z,t,w,R;long long sum[N],flag[N],ans,a[N],belong[N];inline long long read(){ int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}int main(){ n=read();t=sqrt(n); for(int i=1;i<=n;i++) { a[i]=read();belong[i]=(i-1)/t+1; sum[belong[i]]+=a[i]; } m=read(); for(int i=1;i<=m;i++) { w=read(); if(w==1) { x=read();y=read();z=read();R=min(y,belong[x]*t); for(int i=x;i<=R;i++) a[i]+=z,sum[belong[i]]+=z; for(int i=belong[x]+1;i
区间修改+区间查询

 

转载于:https://www.cnblogs.com/L-Memory/p/6939651.html

你可能感兴趣的文章
Wannafly模拟赛5 A 思维 D 暴力
查看>>
【Linux开发】CCS远程调试ARM,AM4378
查看>>
Linux之ssh服务介绍
查看>>
排序:冒泡排序
查看>>
Java中instanceof关键字的用法总结
查看>>
引用类型-Function类型
查看>>
(转)Android 仿订单出票效果 (附DEMO)
查看>>
数据库多张表导出到excel
查看>>
微信小程序去除button默认样式
查看>>
Where does Visual Studio look for C++ Header files?
查看>>
Java打包可执行jar包 包含外部文件
查看>>
Windows Phone开发(37):动画之ColorAnimation
查看>>
js中escape,encodeURI,encodeURIComponent 区别(转)
查看>>
sass学习笔记-安装
查看>>
Flask (二) cookie 与 session 模型
查看>>
修改添加网址的教程文件名
查看>>
[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)
查看>>
裁剪图片
查看>>
数据结构实习 problem L 由二叉树的中序层序重建二叉树
查看>>
VS中展开和折叠代码
查看>>