vj线段树专题题解

单点更新模板

void build(int x,int l,int r){//sum[x]控制l-r区域
if(l==r){Sum[x]=num[l];return ;}
int mid=l+((r-l)>>1);
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
void add(int a,int b,int l,int r,int x){//num[a]+=b,Sum[x] x=1 单点a增加b
if(l==r&&a==l){Sum[x]+=b;return ;}
int mid=l+((r-l)>>1);
if(a<=mid) add(a,b,l,mid,x<<1);//这里条件判断只和a有关,num[a]
else add(a,b,mid+1,r,x<<1|1);
Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
int query(int a,int b,int l,int r,int x){//range[a,b] query from x 查询区域a-b之间信息
if(a<=l&&r<=b) return Sum[x];
int mid=l+((r-l)>>1);
if(b<=mid) return query(a,b,l,mid,x<<1);//这里和a,b都有关
if(a>mid) return query(a,b,mid+1,r,x<<1|1);
return query(a,b,l,mid,x<<1)+query(a,b,mid+1,r,x<<1|1);
}

区间更新模板

void build(int x,int l,int r){
if(l==r){Sum[x]=nums[l];return;}
int mid=l+((r-l)>>1);
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
void pushDown(int x,int len){//len是lazy[p] 管辖的长度
if(lazy[x]){//先下放到下面,然后讲lazy[]置0
Sum[x<<1]+=(long long)lazy[x]*(len-((len)>>1));
Sum[x<<1|1]+=(long long)lazy[x]*(len>>1);
lazy[x<<1]+=lazy[x];//+=不是=
lazy[x<<1|1]+=lazy[x];
lazy[x]=0;
}
}
void add(int x,int a,int b,int c,int l,int r){
if(a<=l&&r<=b){//如果要更新的区间覆盖了当控制的区间,设置lazy标记后结束
lazy[x]+=c;
Sum[x]+=(long long)c*(r-l+1);
return ;
}
pushDown(x,r-l+1);//否则检查是否由lazy标记,pushDown
int mid=l+((r-l)>>1);
if(a<=mid) add(x<<1,a,b,c,l,mid);
if(b>mid) add(x<<1|1,a,b,c,mid+1,r);
Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
long long query(int x,int a,int b,int l,int r){
if(a<=l&&r<=b){return Sum[x];}
pushDown(x,r-l+1);
int mid=l+((r-l)>>1);
if(b<=mid) return query(x<<1,a,b,l,mid);
if(a>mid) return query(x<<1|1,a,b,mid+1,r);
return query(x<<1,a,b,l,mid)+query(x<<1|1,a,b,mid+1,r);
}

题解

a_HDU1166 A - 敌兵布阵

简单的单点更新,动态查询(询问次数很多),是模板题;

每个营地代表一个点,每次查询或更新

代码(略)

B - I Hate It HDU - 1754

代码略

C - A Simple Problem with Integers

区间更新的模板题(lazy标记)

代码略

D - Mayor's posters

令人难受的非动态查询的线段树题目

题解

  • 每次贴不同宽度的海报,问经过最后能看见几张海报
  • 离散化+线段树,离散化时注意>1意味着并非紧邻,蓑衣离散化后也应该保持非紧邻
  • unique,sort,lower_bound函数的参数都是.end(),可以理解为最后一个元素的下一位

附上代码

//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define maxn 20010
struct poster{
int lb,rb;//left bound
};
poster ps[10010];
int a[maxn<<1],b[maxn<<1];
int col[maxn<<3];//维护区间海报颜色种数
bool has[maxn];//维护区间某种颜色知否被标记 int n,ans;
void pushdown(int rt){
if(col[rt]){
col[rt<<1]=col[rt<<1|1]=col[rt];
col[rt]=0;
}
}
void update(int rt,int l,int r,int x,int y,int co){
//在区间x-y贴颜色co的海报(区间更新)
if(x<=l&&r<=y){
col[rt]=co;
return ;
}
if(l==r) return ;
pushdown(rt);
int mid=(l+r)>>1;
if(x<=mid) update(rt<<1,l,mid,x,y,co);
if(y>mid) update(rt<<1|1,mid+1,r,x,y,co);
//因为不是动态询问,所以不用子节点更新父节点
//而动态询问实际上信息很难维护,这也应该是出题人考虑到了 }
void query(int rt,int l,int r){
if(col[rt]){
if(!has[col[rt]]) ans++;//该颜色尚未计数
has[col[rt]]=true;
return ;
}
if(l==r) return ;
int mid=(l+r)>>1;
query(rt<<1,l,mid);
query(rt<<1|1,mid+1,r);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
//init
memset(col,0,sizeof(col));
memset(has,0,sizeof(has));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
ans=0;
int cnt=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %d",&ps[i].lb,&ps[i].rb);
a[cnt++]=ps[i].lb;//a[]用于排序和离散化
a[cnt++]=ps[i].rb; }
//cout<<"db ok \n"<<endl;
sort(a,a+cnt);
cnt=unique(a,a+cnt)-a;
int cnt2=1;
b[cnt2]=a[0];
for(int i=1;i<cnt;i++){
//printf("%d %d\n",i,a[i]);
if(a[i]-a[i-1]>1){
//加点
b[++cnt2]=a[i]-1;
b[++cnt2]=a[i];
}
else{
b[++cnt2]=a[i];
}
}
//cout<<"db ok 2\n"<<cnt2<<"cnt2\n"<<endl;
//离散化完成 b[]用于建立线段树
//距离>2的点实际并不紧邻
for(int i=1;i<=n;i++){
int x=lower_bound(b+1,b+cnt2+1,ps[i].lb)-b;
int y=lower_bound(b+1,b+cnt2+1,ps[i].rb)-b;
// cout<<x<<" "<<y<<" "<<endl;
// cout<<"db ok 4\n"<<endl;
update(1,1,cnt2,x,y,i);
}
//cout<<"db ok 3\n"<<endl;
query(1,1,cnt2);
printf("%d\n",ans); }
return 0;
}

vj线段树专题的更多相关文章

  1. zkw线段树专题

    题目来自大神博客的线段树专题 http://www.notonlysuccess.com/index.php/segment-tree-complete/ hdu1166 敌兵布阵题意:O(-1)思路 ...

  2. 2018 UESTC 线段树专题

    A - 一棵简单的线段树 A[1...n]初始全为0. 1. 给两个数p 和 x(1≤p≤n),单点更新 A[p] <- x 2. 给两个数L和R (1≤L<R≤n),  L到R区间里这几 ...

  3. Kuangbin 带你飞-线段树专题 题解

    HDU 1166 敌兵布阵 单调更新区间查询和 #include <map> #include <set> #include <list> #include < ...

  4. 线段树专题—ZOJ1610 Count the Colors

    题意:给一个n,代表n次操作,接下来每次操作表示把[l.r]区间的线段涂成k的颜色当中,l,r,k的范围都是0到8000 分析:事实上就是拿线段树维护一段区间的颜色,整体用到的是线段树的区间更新把,可 ...

  5. 线段树专题 POJ3468 A Simple Problem with Integers

    题意:n个点.m个操作.两种操作类型.C X Y K 表示区间[x,y]上每一个点值加k.Q X Y 求区间[x,y]的和 分析:线段树区间求和,裸模板 注意:结果会超int,要用long long ...

  6. 线段树专题2-(加强版线段树-可持续化线段树)主席树 orz! ------用于解决区间第k大的问题----xdoj-1216

    poj-2104(区间第K大问题) #include <iostream> #include <algorithm> #include <cstdio> #incl ...

  7. 线段树专题—ZOJ1610 Count the Colors(涂区间,直接tag标记)

    Painting some colored segments on a line, some previously painted segments may be covered by some th ...

  8. 线段树专题—HDU1698 Just a Hook

    题意:t组数据,给一个n.m表示n长度的钩和m次操作.初始钩子的每单位长度的价值为1,接下来输入 x,y,k 的操作把钩子[x,y]区间的价值替换为k,求m次操作后钩子的价值为多少 分析:成段替换.最 ...

  9. kuangbin专题七 ZOJ1610 Count the Colors (灵活线段树)

    Painting some colored segments on a line, some previously painted segments may be covered by some th ...

随机推荐

  1. VS2015 C++ 获取 Edit Control 控件的文本内容,以及把获取到的CString类型的内容转换为 int 型

    UpdateData(true); //读取编辑框内容,只要建立好控件变量后调用这个函数使能,系统就会自动把内容存在变量里 //这里我给 Edit Control 控件创建了一个CString类型.V ...

  2. Codeforces 919D Substring (拓扑图DP)

    手动博客搬家: 本文发表于20180716 10:53:12, 原地址https://blog.csdn.net/suncongbo/article/details/81061500 给定一个\(n\ ...

  3. FZU - 2062 - Suneast & Yayamao

    先上题目: Problem 2062 Suneast & Yayamao Accept: 146    Submit: 319Time Limit: 1000 mSec    Memory L ...

  4. try finnlay 总结

    public class FinnallyTest { public static void main(String[] args){ System.out.print(go()); } public ...

  5. [bzoj1212][HNOI2004]L语言_AC自动机_动态规划

    L语言 bzoj-1212 HNOI-2004 题目大意:给你一个n个单词的集合,然后给你m条字符串.问每条字符串可以被理解的最长前缀.被理解当且仅当存在一种分割使得每一段都是集合里的元素. 注释:$ ...

  6. Codeforces Round #253 (Div. 1)-A,B

    A题: 由题意可知,最多翻10次就能够(事实上8次就够了).那么我们就用状态压缩表示状态. 对于某种状态,假设某一位为0,那么代表这一位不翻,否则代表这一位翻. 对于某一种翻的状态: 假设牌中有G3, ...

  7. DecimalFormat格式化输出带小数的数字类型

    刚開始 double d = 333333333.333333333; System.out.println(d); 输出结果为3.333333333333333E8 网上找到了DecimalForm ...

  8. oc14--匿名对象

    // // main.m // 匿名对象 #import <Foundation/Foundation.h> #import "Person.h" #import &q ...

  9. 【POJ 1222】 EXTENDED LIGHTS OUT

    [题目链接] http://poj.org/problem?id=1222 [算法] 列出异或方程组,用高斯消元求解即可 [代码] #include <algorithm> #includ ...

  10. [HTML5] 让IE支持HTML5的方法

    越来越多的站点开始使用 HTML5 标签,但是目前的情况是还有很多人在使用IE6.IE7.IE8.为了让所有浏览者都可以正常的访问,解决方案有下面两个: 1.为网站创建多套模板,通过程序对User-A ...