[kuangbin]线段树
[kuangbin]线段树
2019.07.08
1.HDU 1166 敌兵布阵
1.1题目描述
单点修改+区间查询
1.2代码
#include <cstdio>
#include <iostream>
#define mid ((tr[d].l + tr[d].r) >> 1)
#define sl d*2
#define sr d*2+1
using namespace std;
const int N = 50005;
int T,n;
int a[N];
string Q;
struct Tree{
int l,r;
int sum;
}tr[N*8];
void build(int d,int l,int r){
tr[d].l = l,tr[d].r = r;
if (l == r){
tr[d].sum = a[l];
return;
}
build(sl,l,mid);
build(sr,mid+1,r);
tr[d].sum = tr[sl].sum + tr[sr].sum;
}
void modify(int d,int x,int w){
if (tr[d].l == x && tr[d].r == x){
tr[d].sum += w;
return;
}
if (x <= mid) modify(sl,x,w);
else modify(sr,x,w);
tr[d].sum = tr[sl].sum + tr[sr].sum;
}
int query(int d,int l,int r){
if (tr[d].l == l && tr[d].r == r){
return tr[d].sum;
}
if (r <= mid) return query(sl,l,r);
else if (l > mid) return query(sr,l,r);
else return query(sl,l,mid)+query(sr,mid+1,r);
}
int main(){
scanf("%d",&T);
for (int t = 1;t <= T;t++){
scanf("%d",&n);
for (int i = 1;i <= n;++i){
scanf("%d",a+i);
}
printf("Case %d:\n",t);
build(1,1,n);
while(cin >> Q && Q != "End"){
int u,v;
scanf("%d%d",&u,&v);
if (Q == "Query"){
printf("%d\n",query(1,u,v));
}else if (Q == "Add"){
modify(1,u,v);
}else if (Q == "Sub"){
modify(1,u,-v);
}
}
}
}
2.HDU 1754 I Hate It
2.1 题目描述
单点修改+区间查询
2.2 代码
#include <cstdio>
#include <iostream>
#include <cmath>
#define mid ((tr[d].l + tr[d].r) >> 1)
#define sl d*2
#define sr d*2+1
using namespace std;
const int N = 200005;
int m,n,u,v;
int a[N];
string Q;
struct Tree{
int l,r;
int max;
}tr[N*8];
void build(int d,int l,int r){
tr[d].l = l,tr[d].r = r;
if (l == r){
tr[d].max = a[l];
return;
}
build(sl,l,mid);
build(sr,mid+1,r);
tr[d].max = max(tr[sl].max,tr[sr].max);
}
void modify(int d,int x,int w){
if (tr[d].l == x && tr[d].r == x){
tr[d].max = w;
return;
}
if (x <= mid) modify(sl,x,w);
else modify(sr,x,w);
tr[d].max = max(tr[sl].max,tr[sr].max);
}
int query(int d,int l,int r){
if (tr[d].l == l && tr[d].r == r){
return tr[d].max;
}
if (r <= mid) return query(sl,l,r);
else if (l > mid) return query(sr,l,r);
else return max(query(sl,l,mid),query(sr,mid+1,r));
}
int main(){
while(~scanf("%d%d",&n,&m)){
for (int i = 1;i <= n;++i){
scanf("%d",a+i);
}
build(1,1,n);
for (int i = 0;i < m;++i){
cin >> Q;
scanf("%d%d",&u,&v);
if (Q == "Q") printf("%d\n",query(1,u,v));
if (Q == "U") modify(1,u,v);
}
}
}
3.POJ 3468 A Simple Problem with Integers
3.1 题目描述
区间修改+区间查询
3.2 代码
#include <cstdio>
#include <iostream>
#include <cmath>
#define mid ((tr[d].l + tr[d].r) >> 1)
#define sl (d*2)
#define sr (d*2+1)
using namespace std;
const int N = 100005;
typedef long long ll;
int m,n,u,v,w;
int a[N];
string Q;
struct Tree{
int l,r;
ll sum,tag;
}tr[N*8];
int len(int d){
return (tr[d].r - tr[d].l + 1);
}
void build(int d,int l,int r){
tr[d].l = l,tr[d].r = r,tr[d].tag = 0;
if (l == r){
tr[d].sum = a[l];
return;
}
build(sl,l,mid);
build(sr,mid+1,r);
tr[d].sum = tr[sl].sum + tr[sr].sum;
}
void pushdown(int d){
tr[sl].sum += tr[d].tag*len(sl);
tr[sr].sum += tr[d].tag*len(sr);
tr[sl].tag += tr[d].tag;
tr[sr].tag += tr[d].tag;
tr[d].tag = 0;
}
void modify(int d,int l,int r,int w){
if (tr[d].l == l && tr[d].r == r){
tr[d].sum += w*(r-l+1);
tr[d].tag += w;
return;
}
pushdown(d);
if (r <= mid) modify(sl,l,r,w);
else if (l > mid) modify(sr,l,r,w);
else {
modify(sl,l,mid,w);
modify(sr,mid+1,r,w);
}
tr[d].sum = tr[sl].sum + tr[sr].sum;
}
ll query(int d,int l,int r){
if (tr[d].l == l && tr[d].r == r){
return tr[d].sum;
}
pushdown(d);
if (r <= mid) return query(sl,l,r);
else if (l > mid) return query(sr,l,r);
else return query(sl,l,mid) + query(sr,mid+1,r);
}
int main(){
scanf("%d%d",&n,&m);
for (int i = 1;i <= n;++i) scanf("%d",a+i);
build(1,1,n);
for (int i = 1;i <= m;++i){
cin >> Q;
if (Q == "Q"){
scanf("%d%d",&u,&v);
printf("%lld\n",query(1,u,v));
}else if (Q == "C"){
scanf("%d%d%d",&u,&v,&w);
modify(1,u,v,w);
}
}
//system("pause");
return 0;
}
4. POJ 2528 Mayor's posters
4.1题目描述
区间修改+区间查询+离散化
4.2 题解
\(1 <= l_i <= r_i <= 10000000\) 需要离散化处理,同时如果离散化之后两个相邻点之间差大于1,需要在其中间插入一个点以确保不影响统计。
离散化之前点数为2*N,离散化之后再算上插入的点,最多可达4*N。
4.3 代码
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define mid ((tr[d].l + tr[d].r) >> 1)
#define ls (d << 1)
#define rs ((d << 1) | 1)
using namespace std;
const int N = 40005;
int T,n,m;
int l[N],r[N],hash[N];
struct Tr{
int l,r,w;
}tr[N*4];
int ans;
bool vis[N];
void build(int d,int l,int r){
tr[d].l = l,tr[d].r = r,tr[d].w = -1;
if (l == r){
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
}
void pushdown(int d){
if (tr[d].w == -1) return;
tr[ls].w = tr[rs].w = tr[d].w;
tr[d].w = -1;
}
void modify(int d,int l,int r,int w){
if (tr[d].l == l && tr[d].r == r){
tr[d].w = w;
return;
}
pushdown(d);
if (r <= mid) modify(ls,l,r,w);
else if (l > mid) modify(rs,l,r,w);
else {
modify(ls,l,mid,w);
modify(rs,mid+1,r,w);
}
}
void query(int d,int l,int r){
if (tr[d].w != -1){
if (!vis[tr[d].w]){
ans++;
vis[tr[d].w] = 1;
}
return ;
}
if (tr[d].l == tr[d].r) return;
pushdown(d);
query(ls,l,mid);query(rs,mid+1,r);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(vis,0,sizeof(vis));
for (int i = 0;i < n;++i){
scanf("%d%d",l+i,r+i);
hash[i*2] = l[i],hash[i*2+1] = r[i];
}
sort(hash,hash+2*n);
m = unique(hash,hash+2*n) - hash;
int tmpM = m;
for (int i = 1;i < tmpM;++i){
if (hash[i] - hash[i-1] > 1){
hash[m++] = hash[i-1] + 1;
}
}
sort(hash,hash+m);
build(1,0,m-1);
for (int i = 0;i < n;++i){
l[i] = lower_bound(hash,hash+m,l[i]) - hash;
r[i] = lower_bound(hash,hash+m,r[i]) - hash;
modify(1,l[i],r[i],i);
}
ans = 0;
query(1,0,m-1);
printf("%d\n",ans);
}
return 0;
}