目录

  • 1264. 动态求连续区间和 【树状数组板子题】
  • 1265. 数星星 【树状数组变种】
  • 1270. 数列区间最大值 【线段树 / 区间内求最大值】
  • 1215. 小朋友排队 【树状数组】
  • AcWing 1228. 油漆面积 【扫描线】
  • AcWing 1232. 三体攻击 【不会 三维差分】
  • AcWing 1237. 螺旋折线 【找规律】
  • 797. 差分 【板子题】
  • 798. 差分矩阵 【板子题】

1264. 动态求连续区间和 【树状数组板子题】


树状数组解法:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,a[N],tr[N];
int lowbit(int x)
{return x & -x;
}
void add(int x,int v)
{for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=v;
}
int query(int x)
{int res=0;for(int i=x;i;i-=lowbit(i)) res+=tr[i]; return res;
}
int main(void)
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",&a[i]);for(int i=1;i<=n;i++) add(i,a[i]);while(m--){int k,x,y;scanf("%d%d%d",&k,&x,&y);if(k==0) printf("%d\n",query(y)-query(x-1));else add(x,y);}return 0;
}

线段树写法:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m;
int w[N];
struct Node
{int l,r;int sum;
}tr[N*4];
void pushup(int u)
{tr[u].sum=tr[u<<1].sum+tr[u<<1 | 1].sum;
}
void build(int u,int l,int r)
{if(l==r) tr[u]={l,r,w[r]};else{tr[u]={l,r};int mid=(l+r)>>1;build(u<<1,l,mid),build(u<<1 | 1,mid+1,r);pushup(u);}
}
int query(int u,int l,int r)
{if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;int mid=(tr[u].l+tr[u].r)>>1;int sum=0;if(l<=mid) sum=query(u<<1,l,r);if(r>mid) sum+=query(u<<1 | 1,l,r);return sum;
}
void modify(int u,int x,int v)
{if(tr[u].l==tr[u].r) tr[u].sum+=v;else{int mid=(tr[u].l+tr[u].r)>>1;if(x<=mid) modify(u<<1,x,v);else modify(u<<1 | 1,x,v);pushup(u);}
}
int main(void)
{cin>>n>>m;for(int i=1;i<=n;i++) cin>>w[i];build(1,1,n);int k,a,b;while(m--){cin>>k>>a>>b;if(k==0) printf("%d\n",query(1,a,b));else modify(1,a,b);}return 0;
}

1265. 数星星 【树状数组变种】

#include<bits/stdc++.h>
using namespace std;
const int N=32005;
int tr[N],n,st[N];
int lowbit(int x)
{return x & -x;
}
void add(int x)
{for(int i=x;i<N;i+=lowbit(i)) tr[i]++;
}
int query(int x)
{int res=0;for(int i=x;i;i-=lowbit(i)) res+=tr[i];return res;
}
int main(void)
{cin>>n;for(int i=0;i<n;i++){int x,y; cin>>x>>y;x++;st[query(x)-query(0)]++;add(x);}for(int i=0;i<n;i++) cout<<st[i]<<endl;return 0;
}

1270. 数列区间最大值 【线段树 / 区间内求最大值】

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m;
int w[N];
struct Node
{int l,r;int sum;
}tr[N*4];
void pushup(int u)
{tr[u].sum=max(tr[u<<1].sum,tr[u<<1 | 1].sum);
}
void build(int u,int l,int r)
{if(l==r) tr[u]={l,r,w[r]};else{tr[u]={l,r};int mid=(l+r)>>1;build(u<<1,l,mid),build(u<<1 | 1,mid+1,r);pushup(u);}
}
int query(int u,int l,int r)
{if(tr[u].l>=l&&tr[u].r<=r) return tr[u].sum;int mid=(tr[u].l+tr[u].r)>>1;int sum=0;if(l<=mid) sum=query(u<<1,l,r);if(r>mid) sum=max(sum,query(u<<1 | 1,l,r));return sum;
}
int main(void)
{cin>>n>>m;for(int i=1;i<=n;i++) scanf("%d",&w[i]);build(1,1,n);int a,b;while(m--){scanf("%d%d",&a,&b);printf("%d\n",query(1,a,b));}return 0;
}

1215. 小朋友排队 【树状数组】

每个数所对应的换位次数(逆序对)=前面比它大的+后面比它小的
树状数组维护的是每一个身高所对应的个数
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e6+10;
int n;
int h[N],tr[N];
int sum[N];
int lowbit(int x)
{return x&-x;
}
void add(int x,int v)
{for(int i=x;i<N;i+=lowbit(i)) tr[i]+=v;
}
int query(int x)
{int res=0;for(int i=x;i;i-=lowbit(i)) res+=tr[i];return res;
}
int main(void)
{scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&h[i]),h[i]++;for(int i=0;i<n;i++){sum[i]=query(N-1)-query(h[i]);add(h[i],1);}memset(tr,0,sizeof tr);for(int i=n-1;i>=0;i--){sum[i]+=query(h[i]-1);add(h[i],1);}LL res=0;for(int i=0;i<n;i++) res+=sum[i]*(sum[i]+1ll)/2;cout<<res;return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
typedef unsigned long long int LL;
LL h[N],st[N],n;
int tr1[N],tr2[N];
int lowbit(int x){return x&(-x);}
void add(int tr[],int x,int v)
{for(int i=x;i<N;i+=lowbit(i)) tr[i]+=v;
}
int query(int tr[],int x)
{int sum=0;for(int i=x;i;i-=lowbit(i)) sum+=tr[i];return sum;
}
int main(void)
{cin>>n;for(int i=1;i<=n;i++) cin>>h[i],h[i]++,st[h[i]]++;for(int i=1;i<N;i++) add(tr2,i,st[i]);for(int i=1;i<=n;i++){add(tr2,h[i],-1);st[i]=query(tr1,N-1)-query(tr1,h[i])+query(tr2,h[i]-1);//前面比它大的,后面比他小的。add(tr1,h[i],1);}LL ans=0;for(int i=1;i<=n;i++) ans+=1ll*st[i]*(st[i]+1)/2;cout<<ans;return 0;
}

AcWing 1228. 油漆面积 【扫描线】

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*3+10;
int n;
struct Segment
{double x,y1,y2;bool operator< (const Segment &t)const{return x<t.x;}int k;
}seg[N*2];
struct Node
{int l,r;int cnt;//当前区间被覆盖的次数double len;//子区间总共被覆盖的长度
}tr[N*8];
vector<double>ys;int find(double y)
{return lower_bound(ys.begin(),ys.end(),y)-ys.begin();
}void pushup(int u)
{if(tr[u].cnt) tr[u].len=ys[tr[u].r+1]-ys[tr[u].l];else if(tr[u].l!=tr[u].r){tr[u].len=tr[u*2].len+tr[u*2+1].len; }else tr[u].len=0;
}void build(int u,int l,int r)
{tr[u]={l,r,0,0};if(l!=r){int mid=(l+r)/2;build(u*2,l,mid),build(u*2+1,mid+1,r);}
}void modify(int u,int l,int r,int k)
{if(l<=tr[u].l&&tr[u].r<=r){tr[u].cnt+=k;pushup(u);}else{int mid=(tr[u].l+tr[u].r)/2;if(l<=mid) modify(u*2,l,r,k);if(r>mid) modify(u*2+1,l,r,k);pushup(u);}
}int main()
{cin>>n;for(int i=0,j=0;i<n;i++){double x1,y1,x2,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);seg[j++]={x1,y1,y2,1};seg[j++]={x2,y1,y2,-1};ys.push_back(y1),ys.push_back(y2);}sort(ys.begin(),ys.end());ys.erase(unique(ys.begin(),ys.end()),ys.end());build(1,0,ys.size()-2);sort(seg,seg+n*2);long long int res=0;for(int i=0;i<n*2;i++){if(i>0) res+=tr[1].len*(seg[i].x-seg[i-1].x);modify(1,find(seg[i].y1),find(seg[i].y2)-1,seg[i].k);}printf("%lld",res);
}

AcWing 1232. 三体攻击 【不会 三维差分】

AcWing 1237. 螺旋折线 【找规律】

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
int x;
int y;
long long ans;
int main(void)
{cin>>x>>y;if(abs(x)<=y&&y>=0)//上{if(x>=0)ans=(long long)(2*y)*(2*y)-(y-x);elseans=(long long)(2*y)*(2*y-1)+(y-abs(x));}if(abs(y)<=x&&x>=0)//左{if(y>=0)ans=(long long)(2*x)*(2*x)+(x-y);elseans=(long long)(2*x)*(2*x+1)-(x-abs(y));}if(abs(x)<=abs(y)+1&&y<0)//下{if(x>=0)ans=(long long)(2*abs(y))*(2*abs(y)+1)+(abs(y)-x);elseans=(long long)(2*(abs(y)+1)-1)*(2*(abs(y)+1)-1)-(abs(y)+1-abs(x));}if(abs(y)<=abs(x)-1&&x<0)//右{if(y>=0)ans=(long long)(2*abs(x))*(2*abs(x)-1)-(abs(x)-y);elseans=(long long)(2*abs(x)-1)*(2*abs(x)-1)+(abs(x)-1-abs(y));}cout<<ans<<endl;return 0;
}

797. 差分 【板子题】

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int a[N],b[N],n,m;
void insert(int l,int r,int c)
{b[l]+=c;b[r+1]-=c;
}
int main(void)
{cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i],insert(i,i,a[i]);while(m--){int l,r,c; cin>>l>>r>>c;insert(l,r,c);}for(int i=1;i<=n;i++) b[i]+=b[i-1],cout<<b[i]<<" ";return 0;
}

798. 差分矩阵 【板子题】

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int a[N][N],b[N][N],n,m,k;
void insert(int x,int y,int xx,int yy,int c)
{b[x][y]+=c;b[xx+1][y]-=c;b[x][yy+1]-=c;b[xx+1][yy+1]+=c;
}
int main(void)
{cin>>n>>m>>k;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j],insert(i,j,i,j,a[i][j]);while(k--){int x,y,xx,yy,c; cin>>x>>y>>xx>>yy>>c;insert(x,y,xx,yy,c);}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+b[i][j];cout<<b[i][j]<<" ";}cout<<endl;}
}

第五讲 树状数组与线段树 【未完结】相关推荐

  1. BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j)if(a[j ...

  2. 2019南昌网络赛  I. Yukino With Subinterval 树状数组套线段树

    I. Yukino With Subinterval 题目链接: Problem Descripe Yukino has an array \(a_1, a_2 \cdots a_n\). As a ...

  3. 树状数组及线段树入门(SDNU1665-1668)

    目录 前言 树状数组 先导 单点修改区间查询 区间修改区间查询 线段树 先导 单点修改区间查询--递归形式 单点修改区间查询--非递归形式 区间修改区间查询--递归形式 区间修改区间查询--非递归形式 ...

  4. AcWing 蓝桥杯AB组辅导课 05、树状数组与线段树

    文章目录 前言 一.树状数组 1.1.树状数组知识点 1.2.树状数组代码模板 模板题:AcWing 1264. 动态求连续区间和 例题 例题1.AcWing 1265. 数星星[中等,信息学奥赛一本 ...

  5. LibreOJ 6277,6278,6280 数列分块入门1,2,4 树状数组,分块,线段树等.

    分块1 分块2 分块4 模板一共有九个.我试着在三天内做了3个. 应该不用超链接吧. 分块1 区间加,单点询问. 这不是裸的改版树状数组吗?用树状数组处理前缀和水过. #include<bits ...

  6. 第五讲---树状数组与线段树(上课)

    1.树状数组 树状数组就是c[x],存的值就是原数组中(下标从1开始)[x-lowbit(x),x]这一段区间的前缀和. 1.1动态求连续区间和 #include <cstdio> #in ...

  7. LeetCode Range Sum Query - Mutable(树状数组、线段树)

    问题:给出一个整数数组,求出数组从索引i到j范围内元素的总和.update(i,val)将下标i的数值更新为val 思路:第一种方式是直接根据定义,计算总和时直接计算从i到j的和 第二种方式是使用树状 ...

  8. POJ-3067 Japan(树状数组、线段树)

    题目链接 Description Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built f ...

  9. P1975-[国家集训队]排队【树状数组套线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P1975 题目大意 一个nnn个数字的序列,每次交换两个数,求逆序对. 解题思路 显然交换lll和rrr的话对[1. ...

最新文章

  1. 【linux】Valgrind工具集详解(一):简介
  2. 【自用】 sklearn 用 train_test_split 简单划分训练和测试集
  3. C#设计模式系列:原型模式(Prototype)
  4. 【Android 应用开发】多点触控 ( 多点触控事件 | PointerId | PointerIndex | 坐标获取 | 触摸点个数 )
  5. Excel exportExcel.cs 一个生成.xls文件的例子
  6. 微信小程序 wx:for
  7. 如何使一维数组一行一行的输出成二维数组的格式
  8. 单点登陆(SSO)组件的设计与实现一 【转】
  9. Codeforces 869C The Intriguing Obsession
  10. EL表达式中fn函数
  11. chanlist.php,Nginx+FastCgi+Php 的工作机制
  12. normalize.css v2.1.2 翻译
  13. re模块常用修饰符_re模块中常用功能函数
  14. MySQL 数据库性能优化
  15. HD Tune Pro硬盘检测工具官方版
  16. LTO磁带机清洁准则
  17. U盘引导启动LINUX
  18. 网页设计大作业成品_成品衣柜尺寸太固定,设计师6大方面分享定制衣柜,读后收获满满...
  19. TMS320C6678开发笔记---IBL编译与分析5
  20. 达梦数据文件误删了恢复

热门文章

  1. Python NLPIR2016 与 wordcloud 结合生成中文词云
  2. WRF用户手册翻译:Chapter 5: WRF Model
  3. C#获取文件夹下指定格式的所有文件
  4. 十进制转换成二进制列表
  5. zabbix查看数据
  6. HDU 4630 No Pain No Game 树状数组+离线操作
  7. 人的执念真的是非常的可怕
  8. linux内核之 phys_to_virt
  9. 论文《Attention Is All You Need》及Transformer模型
  10. Boost Asio总结(5)class tcp