1.统计颜色,或运算的运用
2.区间第k大数
3.一个很经典的题
5.求区间相等数字的个数
6.RMQ模板题,区间最大值和最小值的差

1.很好的思路,用或运算来避免左右儿子树总相同颜色的情况。由于
T颜色种类最多30种,__int64 足够用了。
注意初始化就行。

5.关键是写对make_up()这个函数,向上更新需要考虑的问题。经典题型。

1001

 /*

 求区间[l,r]中,颜色的总类。
如何避免重复?----或运算。 */ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define HH 1
using namespace std; struct node
{
int l;
int r;
int color;
__int64 num;
}f[*]; void build(int l,int r,int n)
{
int mid=(l+r)/;
f[n].l=l;
f[n].r=r;
f[n].color=;
f[n].num=<<;
if(l==r)
return ;
build(l,mid,n*);
build(mid+,r,n*+);
} void make_down(int n)
{
f[n*].color=f[n*+].color=HH; f[n*].num=f[n*+].num=f[n].num; f[n].color=;
f[n].num=;
} void update(int l,int r,int num,int n)
{
int mid=(f[n].l+f[n].r)/; if(f[n].l==l && f[n].r==r)
{
f[n].color=HH;
f[n].num=<<num;
return;
}
if(f[n].color==HH)
make_down(n);
if(mid>=r)
update(l,r,num,n*);
else if(mid<l)
update(l,r,num,n*+);
else
{
update(l,mid,num,n*);
update(mid+,r,num,n*+);
}
f[n].num=f[n*].num|f[n*+].num;
} __int64 query(int l,int r,int n)
{
int mid=(f[n].l+f[n].r)/;
__int64 cur=;
if(f[n].l==l && f[n].r==r)
{
return f[n].num;
}
if(f[n].color==HH)
make_down(n);
if(mid>=r)
cur=query(l,r,n*);
else if(mid<l)
cur=query(l,r,n*+);
else
{
cur=query(l,mid,n*)|query(mid+,r,n*+);
}
f[n].num=f[n*].num|f[n*+].num;
return cur; } int Get_num(__int64 num) //得到1的个数 很优化的算法。
{
int count=;
while(num)
{
++count;
num=(num-)&num;
}
return count;
} void make_ini(int L,int T,int O)
{
int A,B,num,hxl;
__int64 tmp;
char a[];
while(O--)
{
scanf("%s",a);
if(a[]=='C')
{
scanf("%d%d%d",&A,&B,&num);
if(A>B)
{
hxl=A;
A=B;
B=hxl;
}
if(num<=T)
update(A,B,num,);
}
else if(a[]=='P')
{
scanf("%d%d",&A,&B);
if(A>B)
{
hxl=A;
A=B;
B=hxl;
}
tmp=query(A,B,);
printf("%d\n",Get_num(tmp));
}
}
} int main()
{
int L,T,O;
while(scanf("%d%d%d",&L,&T,&O)>)
{
build(,L,);
make_ini(L,T,O);
}
return ;
}

1002

 /*
第k小的数 */ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define NN 100010
using namespace std; int toleft[][NN];
int Tree[][NN];
int Sort[NN]; void build(int l,int r,int dep)
{
int mid=(l+r)/,sum=mid-l+,lpos,rpos,i;
if(l==r) return ;
for(i=l;i<=r;i++)
if(Tree[dep][i]<Sort[mid]) sum--;
lpos=l;
rpos=mid+;
for(i=l;i<=r;i++)
{
if(Tree[dep][i]<Sort[mid])
{
Tree[dep+][lpos++]=Tree[dep][i];
}
else if(Tree[dep][i]==Sort[mid] && sum>)
{
Tree[dep+][lpos++]=Tree[dep][i];
sum--;
}
else
{
Tree[dep+][rpos++]=Tree[dep][i];
}
toleft[dep][i]=toleft[dep][l-]+lpos-l;
}
build(l,mid,dep+);
build(mid+,r,dep+);
} int query(int L,int R,int l,int r,int k,int dep)
{
int mid=(L+R)/,newl,newr,cur;
if(l==r) return Tree[dep][l];
cur=toleft[dep][r]-toleft[dep][l-];
if(cur>=k)
{
newl=L+toleft[dep][l-]-toleft[dep][L-];
newr=newl+cur-;
return query(L,mid,newl,newr,k,dep+);
}
else
{
newr=r+(toleft[dep][R]-toleft[dep][r]);
newl=newr-(r-l-cur);
return query(mid+,R,newl,newr,k-cur,dep+);
}
} void make_ini(int N,int M)
{
int l,r,k;
while(M--)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",query(,N,l,r,k,));
}
} int main()
{
int N,M,i;
while(scanf("%d%d",&N,&M)>)
{
for(i=;i<=N;i++)
{
scanf("%d",&Tree[][i]);
Sort[i]=Tree[][i];
}
sort(Sort+,Sort++N);
build(,N,);
make_ini(N,M);
}
return ;
}

1003

 #include<cstdio>
#include<iostream>
#include<cstdlib>
#define HH 1 //纯色
using namespace std; struct st
{
__int64 l;
__int64 r;
__int64 num;
__int64 color;
__int64 max;
}f[*];
__int64 date[]; void build(__int64 l,__int64 r,__int64 n)
{
__int64 mid=(l+r)/;
f[n].l=l;
f[n].r=r;
f[n].color=;
f[n].num=;
if(l==r)
{
f[n].max=date[l];
return;
}
build(l,mid,n*);
build(mid+,r,n*+);
f[n].max=f[n*].max+f[n*+].max;
} void make_down(__int64 n)
{ f[n*].num+=f[n].num;
f[n*].color=HH;
f[n*].max+=f[n].num*(f[n*].r-f[n*].l+); f[n*+].num+=f[n].num;
f[n*+].color=HH;
f[n*+].max+=f[n].num*(f[n*+].r-f[n*+].l+); f[n].color=;f[n].num=;
} void update(__int64 l,__int64 r,__int64 num,__int64 n)
{
__int64 mid=(f[n].l+f[n].r)/;
if(f[n].l==l && f[n].r==r)
{
f[n].num+=num;
f[n].max+=num*(f[n].r-f[n].l+);
f[n].color=HH;
return ;
}
if(f[n].color==HH)
make_down(n);
if(mid>=r)
update(l,r,num,n*);
else if(mid<l)
update(l,r,num,n*+);
else
{
update(l,mid,num,n*);
update(mid+,r,num,n*+);
}
f[n].max=f[n*].max+f[n*+].max;
} __int64 query(__int64 l,__int64 r,__int64 n)
{
__int64 mid=(f[n].l+f[n].r)/;
__int64 cur=;
if(f[n].l==l && f[n].r==r)
{
return f[n].max;
}
if(f[n].color==HH)
make_down(n);
if(mid>=r)
cur= query(l,r,n*);
else if(mid<l)
cur= query(l,r,n*+);
else
{
cur+= query(l,mid,n*);
cur+=query(mid+,r,n*+);
}
f[n].max=f[n*].max+f[n*+].max;
return cur;
} int main()
{
__int64 n,q,i,l,r,num;
char a[];
while(scanf("%I64d%I64d",&n,&q)>)
{
for(i=;i<=n;i++)
scanf("%I64d",&date[i]);
build(,n,);
while(q--)
{
scanf("%s",a);
if(a[]=='Q')
{
scanf("%I64d%I64d",&l,&r);
printf("%I64d\n",query(l,r,));
}
else if(a[]=='C')
{
scanf("%I64d%I64d%I64d",&l,&r,&num);
update(l,r,num,);
}
}
}
return ;
}

1005

 /*

 求区间[l,r]中,相等数字的最大个数
试一试能不能A。 */ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std; struct node
{
int l;
int r;
int lmax,rmax,max;
int lnum,rnum;
int len;
}f[*];
int Date[]; int hmax(int x,int y)
{
return x>y? x: y;
} int hmin(int x,int y)
{
return x>y? y:x;
} void make_up(node *father,node *l_child,node *r_child)
{
father->lnum=l_child->lnum;
father->rnum=r_child->rnum;
if(l_child->rnum!=r_child->lnum)
{
father->lmax=l_child->lmax;
father->rmax=r_child->rmax;
father->max=hmax(hmax(father->lmax,father->rmax),
hmax(l_child->max,r_child->max));
}
else
{
father->lmax=(l_child->lmax==l_child->len)? l_child->lmax+r_child->lmax:l_child->lmax;
father->rmax=(r_child->rmax==r_child->len)? r_child->rmax+l_child->rmax:r_child->rmax;
father->max= hmax(hmax(father->lmax,father->rmax),
hmax(l_child->max,
hmax(r_child->max,l_child->rmax+r_child->lmax)));
}
} void build(int l,int r,int n)
{
int mid=(l+r)/;
f[n].l=l;
f[n].r=r;
f[n].len=f[n].r-f[n].l+;
if(l==r)
{
f[n].lnum=Date[l];
f[n].rnum=Date[l];
f[n].lmax=f[n].rmax=f[n].max=;
return ;
}
build(l,mid,n*);
build(mid+,r,n*+);
make_up(&f[n],&f[n*],&f[n*+]);
} int query(int l,int r,int n)
{
int mid=(f[n].l+f[n].r)/,cur=,now1=,now2=; if(f[n].l==l && f[n].r==r)
{
return f[n].max;
}
if(mid>=r)
cur=query(l,r,n*);
else if(mid<l)
cur=query(l,r,n*+);
else
{
now1=query(l,mid,n*);
now2=query(mid+,r,n*+);
if(f[n*].rnum==f[n*+].lnum)
{
cur=hmax(hmax(now1,now2),hmin(mid-l+,f[n*].rmax)+
hmin(r-mid,f[n*+].lmax));
}
else
{
cur=hmax(now1,now2);
}
}
return cur;
} void make_ini(int Q)
{
int l,r;
while(Q--)
{
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r,));
}
} int main()
{
int N,Q,i;
while(scanf("%d",&N)>)
{
if(N==)break;
scanf("%d",&Q);
for(i=;i<=N;i++)
scanf("%d",&Date[i]);
build(,N,);
make_ini(Q);
}
}

1006

 /*
求区间[l,r],最大值和最小值的差值。
*/ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define MAX 1000010
using namespace std; struct node
{
int l;
int r;
int min;
int max;
}f[*];
int Date[]; int hmax(int x,int y)
{
return x>y? x:y;
} int hmin(int x,int y)
{
return x>y? y:x;
} void build(int l,int r,int n)
{
int mid=(l+r)/;
f[n].l=l;
f[n].r=r;
if(l==r)
{
f[n].max=Date[l];
f[n].min=Date[l];
return;
}
build(l,mid,n*);
build(mid+,r,n*+);
f[n].max=hmax(f[n*].max,f[n*+].max);
f[n].min=hmin(f[n*].min,f[n*+].min);
} void query(int l,int r,int *a,int *b,int n)
{
int mid=(f[n].l+f[n].r)/;
if(f[n].l==l && f[n].r==r)
{
if(f[n].min<*a)
*a=f[n].min;
if(f[n].max>*b)
*b=f[n].max;
return;
}
if(mid>=r)
query(l,r,a,b,n*);
else if(mid<l)
query(l,r,a,b,n*+);
else
{
query(l,mid,a,b,n*);
query(mid+,r,a,b,n*+);
}
} int main()
{
int N,Q,i;
int a,b,l,r;
while(scanf("%d%d",&N,&Q)>)
{
for(i=;i<=N;i++)
scanf("%d",&Date[i]);
build(,N,);
while(Q--)
{
scanf("%d%d",&l,&r);
a=MAX;b=-;
query(l,r,&a,&b,);
printf("%d\n",b-a);
}
}
return ;
}

HNCU专题训练_线段树(2)的更多相关文章

  1. HNCU专题训练_线段树(1)

    1.内存控制2.敌兵布阵4.广告牌5.区间第k大数(模板题)6.just a Hook7.I Hate It8.动态的最长递增子序列(区间更新题)9.图灵树10.覆盖的面积14.买票问题16.村庄问题 ...

  2. BZOJ_4636_蒟蒻的数列_线段树+动态开点

    BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...

  3. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  4. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

  5. BZOJ_2124_等差子序列_线段树+Hash

    BZOJ_2124_等差子序列_线段树+Hash Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pL ...

  6. BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心

    BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...

  7. BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树

    BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树 Description Input 第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数 ...

  8. BZOJ_1798_[AHOI2009]维护序列_线段树

    BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...

  9. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

随机推荐

  1. bhp 阅读笔记 OSX 下 setuptools pip 安装

    安装 python-setuptools python-pip 尝试 brew install python-setuptools 失败 brew update 失败 $ cd `brew --pre ...

  2. jQuery基础笔记 事件(6)

    day56 参考:https://www.cnblogs.com/liwenzhou/p/8178806.html#autoid-1-9-6 事件 *****         1. 目前为止学过的绑定 ...

  3. webpack快速入门——实战技巧:webpack优化黑技能

    1.抽离jquery,vue(多个第三方类库抽离) 修改入口文件(webpack.config.js中) entry: { entry: './src/entry.js', jquery:'jquer ...

  4. python相见恨晚的库

    1)基本工具: virtualenv(虚拟环境)pip.setuptools (e.g. easy_install,这些东西肯定要呢)ipython(用了以后,就不再想用普通的python shell ...

  5. while 语句

    /* while循环 格式:while(循环保持条件){需要执行的语句} OC: int i = 0; int sum = 0; while (i <= 10) { sum = i++; } w ...

  6. easyui datagrid里的复选框置灰方法

    easyui datagrid里的复选框置灰方法: $('.datagrid input').prop('disabled',true);//复选框置灰

  7. PCA(主成分分析)和LDA详解

    http://www.cnblogs.com/LeftNotEasy/archive/2011/01/08/lda-and-pca-machine-learning.html http://www.c ...

  8. Mapreduce部署与第三方依赖包管理

    Mapreduce部署是总会涉及到第三方包依赖问题,这些第三方包配置的方式不同,会对mapreduce的部署便捷性有一些影响,有时候还会导致脚本出错.本文介绍几种常用的配置方式: 1. HADOOP_ ...

  9. Javac语法糖之EnumSwitch

    在Switch中可以使用的类型有枚举.字符串类型与整形int类型,下面来具体看这几个类型. 1.switch为枚举类型 枚举类: enum Fruit { APPLE,ORINGE } 调用javac ...

  10. 常用CSS实例

    为表格设置合并边框模型: border-collapse:collapse 规定单元格之间的空间: cellspacing:0 规定内侧边框的哪个部分是可见的: rules:all