博客
关于我
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中地理位置数据扩展geometry的使用心得
查看>>
Mysql中存储引擎简介、修改、查询、选择
查看>>
Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
查看>>
mysql中实现rownum,对结果进行排序
查看>>
mysql中对于数据库的基本操作
查看>>
Mysql中常用函数的使用示例
查看>>
MySql中怎样使用case-when实现判断查询结果返回
查看>>
Mysql中怎样使用update更新某列的数据减去指定值
查看>>
Mysql中怎样设置指定ip远程访问连接
查看>>
mysql中数据表的基本操作很难嘛,由这个实验来带你从头走一遍
查看>>
Mysql中文乱码问题完美解决方案
查看>>
mysql中的 +号 和 CONCAT(str1,str2,...)
查看>>
Mysql中的 IFNULL 函数的详解
查看>>
mysql中的collate关键字是什么意思?
查看>>
MySql中的concat()相关函数
查看>>
mysql中的concat函数,concat_ws函数,concat_group函数之间的区别
查看>>
MySQL中的count函数
查看>>
MySQL中的DB、DBMS、SQL
查看>>
MySQL中的DECIMAL类型:MYSQL_TYPE_DECIMAL与MYSQL_TYPE_NEWDECIMAL详解
查看>>
MySQL中的GROUP_CONCAT()函数详解与实战应用
查看>>