博客
关于我
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五补充部分:SQL逻辑查询语句执行顺序
查看>>
mysql交互式连接&非交互式连接
查看>>
MySQL什么情况下会导致索引失效
查看>>
Mysql什么时候建索引
查看>>
MySql从入门到精通
查看>>
MYSQL从入门到精通(一)
查看>>
MYSQL从入门到精通(二)
查看>>
mysql以下日期函数正确的_mysql 日期函数
查看>>
mysql以服务方式运行
查看>>
mysql优化--索引原理
查看>>
MySQL优化之BTree索引使用规则
查看>>
MySQL优化之推荐使用规范
查看>>
Webpack Critical CSS 提取与内联教程
查看>>
mysql优化概述(范式.索引.定位慢查询)
查看>>
MySQL优化的一些需要注意的地方
查看>>
mysql优化相关
查看>>
MySql优化系列-优化版造数据(存储过程+函数+修改存储引擎)-2
查看>>