博客
关于我
CodeForces - 121E Lucky Array(线段树)
阅读量:194 次
发布时间:2019-02-28

本文共 2381 字,大约阅读时间需要 7 分钟。

题干:

给你n个数a[i],和m组询问。询问包括两种格式add l,r,val和count l,r:

add表示将区间[l,r]的数都加上val;
count表示查询区间[l,r]的数中有多少幸运数字(幸运数字仅由4 米斯达点了个? 和7组成
(如:4,7,47,4477;147则不是))

思路:

区间修改,区间查询,一般就是线段树或者树状数组了。

然后就是要明确维护的值是什么值,首先要维护区间内幸运数字的个数,然后因为要高效的求出修改后的值,所以需要维护区间内的数到幸运数字的距离的最小值及个数,然后每次更新完数据后要根据标记稍微重建一下树。
详细操作见代码…

#include 
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;const int mx =110000;int luck[32]={ 4,7,44,47,74,77,444,447,474,477,744,747,774,777,4444,4447,4474,4477,4744,4747,4774,4777,7444,7447,7474,7477,7744,7747,7774,7777,44444,44447}; //幸运数字数组ll dis[11000],a[mx];struct stu{ int l,r; int x,y,lazy;}tree[4*mx];void pushup(int x) //更新数组的区间值{ int t1=x<<1,t2=(x<<1)+1; if(tree[t1].x==tree[t2].x){ tree[x].x=tree[t1].x; tree[x].y=tree[t1].y+tree[t2].y; } else if(tree[t1].x>tree[t2].x){ tree[x].x=tree[t2].x; tree[x].y=tree[t2].y; } else{ tree[x].x=tree[t1].x; tree[x].y=tree[t1].y; }}void build(int x,int l,int r){ tree[x].l=l; tree[x].r=r; tree[x].lazy=0; if(l==r){ tree[x].x=dis[a[l]]; tree[x].y=1; return; } int m=(l+r)>>1; build(x<<1,l,m); build((x<<1)+1,m+1,r); pushup(x);}void pushdown(int x){ if(tree[x].lazy) //懒标记下放 { int t1=x<<1,t2=(x<<1)+1; tree[t1].lazy+=tree[x].lazy; tree[t2].lazy+=tree[x].lazy; tree[t1].x+=tree[x].lazy; tree[t2].x+=tree[x].lazy; tree[x].lazy=0; }}void updata(int x,int l,int r,int val){ if(l<=tree[x].l&&tree[x].r<=r) { tree[x].x+=val; tree[x].lazy+=val; return; } pushdown(x); int m=(tree[x].l+tree[x].r)>>1; if(m>=r) updata(x<<1,l,r,val); else if(l>m) updata(x<<1|1,l,r,val); else { updata(x<<1,l,m,val); updata(x<<1|1,m+1,r,val); } pushup(x);}int que(int x,int l,int r){ if(tree[x].x) return 0; if(l<=tree[x].l&&tree[x].r<=r) return tree[x].y; pushdown(x); int m=(tree[x].l+tree[x].r)>>1; if(m>=r) return que(x<<1,l,r); if(l>m) return que(x<<1|1,l,r); return que(x<<1,l,m)+que(x<<1|1,m+1,r);}void rebuild(int x){ if(tree[x].x>=0) return; //如果距离为正则不用更新 if(tree[x].l==tree[x].r){ a[tree[x].l]-=tree[x].lazy; //更新根的值 tree[x].x=dis[a[tree[x].l]]; //得到新的距离 tree[x].lazy=0; return; } pushdown(x); rebuild(x<<1); rebuild((x<<1)+1); pushup(x);}int main(){ int n,m,now=0,x,y,z; char ch[10]; scanf("%d%d",&n,&m); for(int i=1;i<=10000;i++){ if(i>luck[now]) now++; dis[i]=luck[now]-i; } for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,1,n); for(int i=0;i

转载地址:http://ughi.baihongyu.com/

你可能感兴趣的文章
Mysql 数据类型一日期
查看>>
MySQL 数据类型和属性
查看>>
mysql 敲错命令 想取消怎么办?
查看>>
Mysql 整形列的字节与存储范围
查看>>
mysql 断电数据损坏,无法启动
查看>>
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>