博客
关于我
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/

你可能感兴趣的文章
MongoDB学习笔记(8)--索引及优化索引
查看>>
MQTT工作笔记0009---订阅主题和订阅确认
查看>>
ms sql server 2008 sp2更新异常
查看>>
MS UC 2013-0-Prepare Tool
查看>>
msbuild发布web应用程序
查看>>
MSB与LSB
查看>>
MSCRM调用外部JS文件
查看>>
MSCRM调用外部JS文件
查看>>
MSEdgeDriver (Chromium) 不适用于版本 >= 79.0.313 (Canary)
查看>>
MsEdgeTTS开源项目使用教程
查看>>
msf
查看>>
MSSQL数据库查询优化(一)
查看>>
MSSQL日期格式转换函数(使用CONVERT)
查看>>
MSTP多生成树协议(第二课)
查看>>
MSTP是什么?有哪些专有名词?
查看>>
Mstsc 远程桌面链接 And 网络映射
查看>>
Myeclipse常用快捷键
查看>>
MyEclipse用(JDBC)连接SQL出现的问题~
查看>>
myeclipse的新建severlet不见解决方法
查看>>
MyEclipse设置当前行背景颜色、选中单词前景色、背景色
查看>>