POJ_3468 A Simple Problem with Integers(线段树区间修改+附线段树模板)
来源:互联网 发布:淘宝直播入口在哪 编辑:程序博客网 时间:2024/06/15 14:40
题目链接
题目大意
中文题目
解决
- 线段树区间修改+求和查询的裸题
- 直接附上代码^_^
#include <algorithm>#include <iostream>#include <cstring>#include <vector>#include <cstdio>#include <string>#include <cmath>#include <queue>#include <set>#include <map>#include <complex>using namespace std;typedef long long ll;typedef long double db;typedef pair<int,int> pii;typedef vector<int> vi;#define de(x) cout << #x << "=" << x << endl#define rep(i,a,b) for(int i=a;i<(b);++i)#define all(x) (x).begin(),(x).end()#define sz(x) (int)(x).size()#define mp make_pair#define pb push_back#define fi first#define se second#define E 1e-6#define INF 0x3f3f3f3f#pragma comment(linker, "/STACK:1024000000,1024000000")void open(){freopen("data.txt","r",stdin);}void out(){freopen("out.txt","w",stdout);}const int maxn = 1e5+5;const int MOD = 1e9 + 7;int a[maxn];ll st[maxn<<2],add[maxn<<2];void build(int o,int l,int r){ if(l==r) st[o] = a[l]; else{ int m = (l+r)>>1; build(o<<1,l,m); build((o<<1)|1,m+1,r); st[o] = st[o<<1]+st[(o<<1)|1]; }}void pushup(int o){ st[o] = st[o<<1]+st[(o<<1)|1];}void pushdown(int o,int l,int r){ if(add[o]){ add[o<<1]+=add[o]; add[(o<<1)|1]+=add[o]; int m = (l+r)>>1; st[o<<1]+=add[o]*(m-l+1); st[(o<<1)|1]+=add[o]*(r-m); add[o] = 0; }}void update(int o,int l,int r,int al,int ar,int addv){ if(al<=l&&ar>=r){ add[o]+=addv; st[o]+=addv*(r-l+1); } else{ pushdown(o,l,r); int m = (l+r)>>1; if(al<=m) update(o<<1,l,m,al,ar,addv); if(ar>=m+1) update((o<<1)|1,m+1,r,al,ar,addv); pushup(o); }}ll query(int o,int l,int r,int ql,int qr){ if(ql<=l && qr>=r) return st[o]; pushdown(o,l,r); int m = (l+r)>>1; ll ans = 0; if(ql<=m) ans+=query(o<<1,l,m,ql,qr); if(qr>=m+1) ans+=query((o<<1)|1,m+1,r,ql,qr); return ans;}int main(){ int n,m; scanf("%d%d",&n,&m); rep(i,1,n+1) scanf("%d",&a[i]); build(1,1,n); rep(i,0,m){ char c; int u,v,w; getchar(); scanf("%c",&c); if(c=='Q'){ scanf("%d%d",&u,&v); printf("%lld\n",query(1,1,n,u,v)); } else{ scanf("%d%d%d",&u,&v,&w); update(1,1,n,u,v,w); } } return 0;}
个人总结的线段树模板
int a[maxn] , st[maxn<<2] , change[maxn<<2] , add[maxn<<2];// st数组用于保存信息,可以是区间最大值、区间最小值、区间和等void build(int o,int l,int r){ if(l==r) st[o] = a[l]; else{ int m = (l+r)>>1; build(o<<1,l,m); build((o<<1)|1,m+1,r); st[o] = st[o<<1]+st[(o<<1)|1]; // st[o] = max(st[o<<1] , st[(o<<1)|1]); // st[o] = min(st[o<<1] , st[(o<<1)|1]); }}/* ——————————单点更新——————————void update(int o,int l,int r,int ind,int ans){ if(l==r) st[o] = ans; else{ int m = (l+r)>>1; if(ind<=m) update(o<<1,l,m,ind,ans); else update((o<<1)|1,m+1,r,ind,ans); st[o] = st[o<<1]+st[(o<<1)|1]; // st[o] = max(st[o<<1] , st[(o<<1)|1]); // st[o] = min(st[o<<1] , st[(o<<1)|1]); }}int query(int o,int l,int r,int ql,int qr){ if(ql>r||qr<l) return -1; //返回一个对查询结果无关的量 if(ql<=1&&qr>=r) return st[o]; int m = (l+r)>>1; int p1 = query(o<<1,l,m,ql,qr) , p2 = query((o<<1)|1,m+1,r,ql,qr); return max(p1,p2);} ————————————END———————— */// ——————以下区间修改——————void pushup(int o){ st[o] = st[o<<1] + st[(o<<1)|1];// st[o] = max(st[o<<1] , st[(o<<1)|1]);// st[o] = min(st[o<<1] , st[(o<<1)|1]);}// ——————————区间加值——————————void pushdown(int o,int l,int r) //pushdown_区间加值{ if(add[o]){ //当前节点上有待更新值 add[o<<1]+=add[o]; //传递至左子节点 add[(o<<1)|1]+=add[o]; //传递至右子节点 int m = (l+r)>>1; st[o<<1]+=add[o]*(m-l+1); st[(o<<1)|1]+=add[o]*(r-m); add[o] = 0; //父亲节点更新信息删除 }}// 用于区间加值,配合add数组使用void update(int o,int l,int r,int al,int ar,int addv){ if(al<=l && ar>=r){ //当前区间被覆盖 add[o]+=addv; st[o]+=addv*(r-l+1); } else{ pushdown(o,l,r); //当前节点更新信息传递至下一层 int m = (l+r)>>1; if(al<=m) update(o<<1,l,m,al,ar,addv); if(ar>=m+1) update((o<<1)|1,m+1,r,al,ar,addv); pushup(o); }}// ——————————END——————————————/* ————————区间改值——————————void pushdown(int o,int l,int r) //pushdown_区间改值{ if(change[o]){ int s = change[o]; change[o<<1] = s; change[(o<<1)|1] = s; int m = (l+r)>>1; st[o<<1] = (m-l+1)*s; st[(o<<1)|1] = (r-m)*s; change[o] = 0; }}// 用于区间改值,配合change数组使用void update(int o,int l,int r,int sl,int sr,int s){ if(sl<=l && sr>=r){ change[o] = s; st[o] = (r-l+1)*s; } else{ pushdown(o,l,r); int m = (l+r)>>1; if(sl<=m) update(o<<1,l,m,sl,sr,s); if(sr>=m+1) update((o<<1)|1,m+1,r,sl,sr,s); pushup(o); }} ——————————END———————————— */int query(int o,int l,int r,int ql,int qr) //区间修改问题查询通用{ if(ql<=l && qr>=r) return st[o]; //当前节点覆盖区间即为所需查询区间 pushdown(o,l,r); //将待查询节点的更新信息传递给子节点 int m = (l+r)>>1; ll ans = 0; if(ql<=m) ans+=query(o<<1,l,m,ql,qr); //查询区间与当前节点左子节点有交集,结果加上左子节点查询结果 if(qr>=m+1) ans+=query((o<<1)|1,m+1,r,ql,qr); //查询区间与当前节点右子节点有交集,结果加上右子节点查询结果 return ans;}
阅读全文
0 0
- POJ_3468 A Simple Problem with Integers(线段树区间修改+附线段树模板)
- A Simple Problem with Integers (POJ_3468) 线段树+区间更新
- POJ_3468 A Simple Problem with Integers(线段树+lazy标记)
- poj_3468.A Simple Problem with Integers(线段树/分块)
- A Simple Problem with Integers(线段树+区间修改+区间询问模板)
- poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
- POJ A Simple Problem with Integers (线段树区间更新区间查询模板)
- 区间线段树-poj 3468-A Simple Problem with Integers
- A Simple Problem with Integers +poj+线段树区间更新
- poj3468 A Simple Problem with Integers 线段树区间更新
- A Simple Problem with Integers(线段树,区间求和)
- Poj3468 A Simple Problem with Integers 线段树、区间更新
- A Simple Problem with Integers (线段树区间更新)
- A Simple Problem with Integers 【线段树】-区间加减求和
- 【poj3468-A Simple Problem with Integers】-线段树区间更新
- 线段树系列-pku-3468-A Simple Problem with Integers-区间修改区间求和
- A Simple Problem with Integers 线段树区间查询+区间修改
- POJ-3468-A Simple Problem with Integers(线段树区间修改+区间求和)
- 详解vue之better-scroll实现轮播图和页面滚动
- [SDOI2009]学校食堂Dining(洛谷2157)
- NavigationView控件
- 【区块链】EVM反编译软件Porosity的使用-mac
- matlib与excel交互
- POJ_3468 A Simple Problem with Integers(线段树区间修改+附线段树模板)
- electron打包
- poj 3013 Big Christmas Tree 最短路 (转换思维,看点不看边)
- maven用变量的方法统一管理jar包版本
- LeetCode-83-Remove Duplicates from Sorted List 链表水题
- 马踏棋盘
- java远程连接数据库
- C语言实验——三个整数和、积与平均值
- 飙车