博客
关于我
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 修改默认字符集为utf8
查看>>
Mysql 共享锁
查看>>
MySQL 内核深度优化
查看>>
mysql 内连接、自然连接、外连接的区别
查看>>
mysql 写入慢优化
查看>>
mysql 分组统计SQL语句
查看>>
Mysql 分页
查看>>
Mysql 分页语句 Limit原理
查看>>
MySQL 创建新用户及授予权限的完整流程
查看>>
mysql 创建表,不能包含关键字values 以及 表id自增问题
查看>>
mysql 删除日志文件详解
查看>>
mysql 判断表字段是否存在,然后修改
查看>>
mysql 协议的退出命令包及解析
查看>>
mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
查看>>
mysql 多个表关联查询查询时间长的问题
查看>>
mySQL 多个表求多个count
查看>>
mysql 多字段删除重复数据,保留最小id数据
查看>>
MySQL 多表联合查询:UNION 和 JOIN 分析
查看>>
MySQL 大数据量快速插入方法和语句优化
查看>>
mysql 如何给SQL添加索引
查看>>