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

10

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

19

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的更多相关文章

  1. bzoj3211花神游历各国&&bzoj3038上帝造题的七分钟2*

    bzoj3211花神游历各国 题意: n个数的序列,m个操作,操作两种:区间开根(向下取整)和区间求和.n≤100000,m≤200000,序列中的数非负且≤109. 题解: 一个≤109的数开6次根 ...

  2. bzoj3038上帝造题的七分钟2

    3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1679  Solved: 713[Submit][Status][Dis ...

  3. Bzoj3038 上帝造题的七分钟2 线段树

    Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1135  Solved: 509 Description XLk觉得<上帝造题的七分钟>不太 ...

  4. Bzoj3038 上帝造题的七分钟2 并查集

    Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1135  Solved: 509 Description XLk觉得<上帝造题的七分钟>不太 ...

  5. TYVJ 1941 BZOJ3038 上帝造题的七分钟2 并查集+树状数组

    背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个 ...

  6. BZOJ3038 上帝造题的七分钟

    Time Limit: 3 Sec Memory Limit: 128 MB Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说, ...

  7. [BZOJ3038]上帝造题的七分钟2 树状数组+并查集

    考试的时候用了两个树状数组去优化,暴力修改,树状数组维护修改后区间差值还有最终求和,最后骗了40分.. 这道题有好多种做法,求和好说,最主要的是开方.这道题过的关键就是掌握一点:在数据范围内,最多开方 ...

  8. 【线段树】bzoj3038 上帝造题的七分钟2 / bzoj3211 花神游历各国

    暴力修改,记录一段是否全部为1或0,若全是了,则不再修改. 注意3211一定要判是否为0,否则会T得惨无人道. #include<cstdio> #include<cmath> ...

  9. [BZOJ3211]花神游历各国&&[BZOJ3038] 上帝造题的七分钟2 树状数组+并查集

    3211: 花神游历各国 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 4057  Solved: 1480[Submit][Status][Discu ...

随机推荐

  1. C++图结构的图结构操作示例

    示例代码: /* By qianshou 2013/10/5明天就要开学了~哎~ */ #include<iostream> using namespace std; /********* ...

  2. 你需要知道的九大排序算法【Python实现】之选择排序

    一.选择排序 基本思想:选择排序的思想非常直接,不是要排序么?那好,我就从所有序列中先找到最小的,然后放到第一个位置.之后再看剩余元素中最小的,放到第二个位置--以此类推,就可以完成整个的排序工作了. ...

  3. nexus4/5/6/7/9/10设备谷歌安卓5.1.1系统底包下载

    https://developers.google.com/android/nexus/images http://www.inexus.co/thread-18488-1-1.html

  4. [置顶] ARM指令集和常用寄存器

    1) ARM指令集 32位的 ARM指令和 16位 的Thumb指令 1,寄存器寻址 MOV R1, R2  //将寄存器R2的值传给寄存器R1 2,立即寻址 MOV R0, #0XFF00 //数据 ...

  5. openwrt上网配置的一些理解(二)

    上一篇里面遇到了只能静态上网的问题,动态不行.所以再接再励,问题总是要解决的,偷懒的下场就是一直停留在菜鸟的水平. 首先分析下问题,要动态上网,首先我要明确不是动态获取不了IP,是获取了,上不了外网. ...

  6. openwrt time sycronize

    三行命令搞定这个. opkg update opkg install ntpclient ntpclient -s -c 0 -h ntp.sjtu.edu.cn 最后把这个 放到 rc.local ...

  7. 1.引入必要的文件 2.加载 UI 组件的方式 4.Parser 解析器

    //引入 jQuery 核心库,这里采用的是 2.0 <scripttype="text/javascript"src="easyui/jquery.min.js& ...

  8. $(document).ready(); $().ready(); $()

    $(document).ready(function(){}); $().ready(function(){}); $(function(){}), 三者效果是一样的,在文档加载完成之后执行()中的代 ...

  9. TravelCMS旅游网站系统前台诞生记-2(后台框架篇)

    经过一个多月的研发,前台页面已基本成型了,已开发了线路和签证两大模块,支持在线支付,微信支付待开发,在这个过程中,发现前端技术远比后台技术注重的细节多,特别是css,比我想象的要难,为了兼容各种浏览器 ...

  10. shell的string operator

    ${varname:-word} 如果varname存在并且不为nil,那么返回varname的值,否则返回word.这个常用来在varname未定义时返回默认值 ${varname:=word} 如 ...