bzoj3038 上帝造题的七分钟2
Description
XLk觉得《上帝造题的七分钟》不太过瘾,于是有了第二部。
"第一分钟,X说,要有数列,于是便给定了一个正整数数列。
第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作。
第三分钟,k说,要能查询,于是便有了求一段数的和的操作。
第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围。
第五分钟,诗人说,要有韵律,于是便有了时间限制和内存限制。
第六分钟,和雪说,要省点事,于是便有了保证运算过程中及最终结果均不超过64位有符号整数类型的表示范围的限制。
第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。"
——《上帝造题的七分钟·第二部》
所以这个神圣的任务就交给你了。
Input
第一行一个整数n,代表数列中数的个数。
第二行n个正整数,表示初始状态下数列中的数。
第三行一个整数m,表示有m次操作。
接下来m行每行三个整数k,l,r,k=0表示给[l,r]中的每个数开平方(下取整),k=1表示询问[l,r]中各个数的和。
Output
对于询问操作,每行输出一个回答。
Sample Input
1 2 3 4 5 6 7 8 9 10
5
0 1 10
1 1 10
1 1 5
0 5 8
1 4 8
Sample Output
7
6
HINT
1:对于100%的数据,1<=n<=100000,1<=l<=r<=n,数列中的数大于0,且不超过1e12。
2:数据不保证L<=R 若L>R,请自行交换L,R,谢谢!
首先,题意是给定一个数列,支持区间所有数开根号,支持区间求和
看到有区间操作又没有插入删除,很容易想到线段树
删除比较好实现,各种乱搞
但是修改用lazy tag没法做o(╯□╰)o
因为一段区间如果刚好覆盖的时候,你发现修改tot是不可行的。因为区间加减的修改值只和区间长度有关,区间每个数开根不必一定要知道区间长度,但是要知道每个数的大小。只知道区间长度显然是不行的。举个例子:告诉你区间长度为2,tot=8,要做开根号操作。你不知道它是4+4还是1+7,前者tot要改为4,后者改为3。所以一定得往下找到单个节点再修改。这样显然要T。
这个之所以难做就在于区间开根号,而注意到开根号的一个性质就是它是根号套根号,这样数字就小的很快。因为是下取整,所以当一个数是0、1的时候就不用做下去了。这样可实现了:搞一个mark标记表示区间内是不是只有0、1,显然标记是可以上传的。修改的时候如果mark=1就不用往下做下去,否则做到叶节点。这样做是可行的,因为a[i]<=10^12。拿起计算器算一下,10^12连开六次根号就是1了,所以可行。
具体看代码吧
#include<cstdio>
#include<cmath>
using namespace std;
long long a[200000];
struct trees{
int l,r,ls,rs;
long long tot;
bool push,mrk;
}tree[1000000];
inline long long read()
{
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,treesize;
inline void update(int k)
{
int ls=tree[k].ls,rs=tree[k].rs;
tree[k].tot=tree[ls].tot+tree[rs].tot;
tree[k].mrk=tree[ls].mrk&&tree[rs].mrk;
}
inline void buildtree(int l,int r)
{
if (l>r) return;
int now=++treesize;
tree[now].l=l;tree[now].r=r;
if(l==r)
{
tree[now].tot=a[l];
tree[now].mrk=(a[l]==0||a[l]==1);
return;
}
int mid=(l+r)>>1;
tree[now].ls=treesize+1;
buildtree(l,mid);
tree[now].rs=treesize+1;
buildtree(mid+1,r);
update(now);
}
inline void change(int now,int l,int r)
{
if (tree[now].mrk)return;
int x=tree[now].l,y=tree[now].r;
if (x==y)
{
tree[now].tot=(long long)sqrt(tree[now].tot);
tree[now].mrk=(tree[now].tot==1||tree[now].tot==0||tree[now].mrk);
return;
}
int mid=(x+y)>>1;
if (mid>=r) change(tree[now].ls,l,r);
else if (mid<l) change(tree[now].rs,l,r);
else
{
change(tree[now].ls,l,mid);
change(tree[now].rs,mid+1,r);
}
update(now);
}
inline long long ask(int now,int l,int r)
{
int x=tree[now].l,y=tree[now].r;
if (x==l&&y==r)return tree[now].tot;
int mid=(x+y)>>1;
if (mid>=r) return ask(tree[now].ls,l,r);
else if(mid<l) return ask(tree[now].rs,l,r);
else return ask(tree[now].ls,l,mid)+ask(tree[now].rs,mid+1,r);
}
int main()
{
n=read();
for (int i=1;i<=n;i++) a[i]=read();
buildtree(1,n);
m=read();
int opr,x,y;
for (int i=1;i<=m;i++)
{
opr=read();
x=read();
y=read();
if (y<x)
{
int t=x;
x=y;
y=t;
}
if(opr==0) change(1,x,y);
if(opr==1) printf("%lld\n",ask(1,x,y));
}
}
bzoj3038 上帝造题的七分钟2的更多相关文章
- bzoj3211花神游历各国&&bzoj3038上帝造题的七分钟2*
bzoj3211花神游历各国 题意: n个数的序列,m个操作,操作两种:区间开根(向下取整)和区间求和.n≤100000,m≤200000,序列中的数非负且≤109. 题解: 一个≤109的数开6次根 ...
- bzoj3038上帝造题的七分钟2
3038: 上帝造题的七分钟2 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1679 Solved: 713[Submit][Status][Dis ...
- Bzoj3038 上帝造题的七分钟2 线段树
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1135 Solved: 509 Description XLk觉得<上帝造题的七分钟>不太 ...
- Bzoj3038 上帝造题的七分钟2 并查集
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1135 Solved: 509 Description XLk觉得<上帝造题的七分钟>不太 ...
- TYVJ 1941 BZOJ3038 上帝造题的七分钟2 并查集+树状数组
背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个 ...
- BZOJ3038 上帝造题的七分钟
Time Limit: 3 Sec Memory Limit: 128 MB Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说, ...
- [BZOJ3038]上帝造题的七分钟2 树状数组+并查集
考试的时候用了两个树状数组去优化,暴力修改,树状数组维护修改后区间差值还有最终求和,最后骗了40分.. 这道题有好多种做法,求和好说,最主要的是开方.这道题过的关键就是掌握一点:在数据范围内,最多开方 ...
- 【线段树】bzoj3038 上帝造题的七分钟2 / bzoj3211 花神游历各国
暴力修改,记录一段是否全部为1或0,若全是了,则不再修改. 注意3211一定要判是否为0,否则会T得惨无人道. #include<cstdio> #include<cmath> ...
- [BZOJ3211]花神游历各国&&[BZOJ3038] 上帝造题的七分钟2 树状数组+并查集
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 4057 Solved: 1480[Submit][Status][Discu ...
随机推荐
- Myeclipse自动生成javabean的get和set方法
用Myeclipse开发java web程序,写javabean的时候,如果字段很多的话,写get和set方法是一件很无语和浪费时间的事情,所以Myeclipse提供了一个自动生成这些方法的功能. 首 ...
- java 定义mysql树形菜单
数据库中的数据如下: 1.首先在Dao中实现查找方法 public List<ProductType> findAllByRoot() { //定义集合,添加ProductType对象 L ...
- JavaScript学习笔记(高级部分—02)
47.switch语句的语法: switch (i) { case 20: alert("20"); break; case 30: alert("30"); ...
- java对象的内存分配
(1) 寄存器(register).这是最快的保存区域,这是主要由于它位于处理器内部.然而,寄存器的数量十分有限,所以寄存器是需要由编译器分配的.我们对此没有直接的控制权,也不可能在自己的程序里找到寄 ...
- java关键字-transient
java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持. Java的serialization提供了一种持久化对象实例的机制.当持久化对象时,可能有 ...
- 使用GCM服务(Google Cloud Messaging)实现Android消息推送
最近在网上查了关于很多Android消息推送的资料,其中主要有四种方法. 1) 使用GCM服务(Google Cloud Messaging) 2) 使用XMPP协议(Openfire + Spark ...
- [Angular 2] implements OnInit, OnDestory for fetching data from server
Link: https://angular.io/docs/js/latest/api/core/OnInit-interface.html, https://www.youtube.com/watc ...
- Android Studio使用教程(一)
今年的Google全球开发者大会虽然没有新的Android系统和设备,但是还是推出了一些不错的产品,Android Studio就是其中之一.这个基于Intellij IDEA开发的Android I ...
- 获取checkboxlist选中的值以及绑定来自之前选中的来自数据库的值
//////ps:一下几句都是一个意思,为的是以后有人搜索关键字的时候能定位到这里///checkboxlist绑定选中值///checkboxlist绑定来之mssql数据的值///checkbox ...
- java 位运算权限管控(转载)
这里笔者介绍一种很常用,也比较专业的权限控制思路.这里用java语言描述,其实都差不多的.要换成其他的语言主,自己转一下就可以了.为了方便起见,我们这里定义a^b为:a的b次方.这里,我们为每一个操作 ...