2492 上帝造题的七分钟 2

题目描述 Description

  XLk觉得《上帝造题的七分钟》不太过瘾,于是有了第二部。

  "第一分钟,X说,要有数列,于是便给定了一个正整数数列。
  第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作。
  第三分钟,k说,要能查询,于是便有了求一段数的和的操作。
  第四分钟,彩虹喵说,要是noip难度,于是便有了数据范围。
  第五分钟,诗人说,要有韵律,于是便有了时间限制和内存限制。
  第六分钟,和雪说,要省点事,于是便有了保证运算过程中及最终结果均不超过64位有符号整数类型的表示范围的限制。
  第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。"
  ——《上帝造题的七分钟·第二部》
  所以这个神圣的任务就交给你了。

输入描述 Input Description

  第一行一个整数n,代表数列中数的个数。
  第二行n个正整数,表示初始状态下数列中的数。
  第三行一个整数m,表示有m次操作。
  接下来m行每行三个整数k,l,r,k=0表示给[l,r]中的每个数开平方(下取整),k=1表示询问[l,r]中各个数的和。
  UPD:注意数据中有可能l>r,所以遇到这种情况请交换l和r。

输出描述 Output Description

  对于询问操作,每行输出一个回答。

样例输入 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

数据范围及提示 Data Size & Hint

  对于30%的数据,1<=n,m<=1000,数列中的数不超过32767。
  对于100%的数据,1<=n,m<=100000,1<=l,r<=n,数列中的数大于0,且不超过1e12。
  注意l有可能大于r,遇到这种情况请交换l,r。

来源:Nescafe 20

【思路】

区间查询+打标记。

  一个关键的思想就是一个数被反复开方并向下取整最终会变为1,如果一个数变成1就不需要对它操作了。

  对于区间开方操作,对于区间中的每一个点都进行操作如果为1则下次不再操作。

  实现1:

BIT+“并查集”。

【代码1】

 //341ms
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long LL;
const int maxn = +; LL a[maxn],p[maxn];
int n,m; LL read() {
char c=getchar();
while(!isdigit(c)) c=getchar();
LL x=;
while(isdigit(c)) {
x=x*+c-'';
c=getchar();
}
return x;
} LL c[maxn];
int lowbit(int x) { return x&(-x); }
LL Sum(LL x) {
LL res=;
while(x>) {
res += c[x];
x-=lowbit(x);
}
return res;
}
void Add(int x,LL d) {
while(x<=n) {
c[x] += d;
x += lowbit(x);
}
}
int find(int x) {
return x==p[x]?x:p[x]=find(p[x]);
} int main() {
n=read();
FOR(i,,n) a[i]=read(),Add(i,a[i]);
FOR(i,,n+) p[i]=i; //n+1为哨兵
m=read();
LL u,v,w;
FOR(i,,m) {
w=read(),u=read(),v=read();
if(u>v) swap(u,v); if(w)
printf("%lld\n",Sum(v)-Sum(u-));
else
{
for(int j=find(u);j<=v;j=find(j+)) {
LL s=sqrt(a[j]);
Add(j,s-a[j]);
a[j]=s;
if(s==) {
p[j]=j+;
if(j==v) break;
}
}
}
}
return ;
}

  实现2:

线段树+结点标记

【代码2】

 //399ms
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long LL;
const int maxn = +; LL a[maxn],p[maxn];
int n,m; LL read() {
char c=getchar();
while(!isdigit(c)) c=getchar();
LL x=;
while(isdigit(c)) {
x=x*+c-'';
c=getchar();
}
return x;
} LL sumv[maxn];
bool f[maxn];
void build(int u,int L,int R) {
int lc=u*,rc=u*+;
if(L==R) {
sumv[u]=a[L];
}
else {
int M=L+(R-L)/;
build(lc,L,M);
build(rc,M+,R);
sumv[u]=sumv[lc]+sumv[rc];
}
}
int ya,yb;
void update(int u,int L,int R) {
int lc=u*,rc=u*+;
if(f[u]) return ;
if(L==R) {
sumv[u]=sqrt(sumv[u]);
if(sumv[u]==) f[u]=;
}
else {
int M=L+(R-L)/;
if(ya<=M) update(lc,L,M);
if(M<yb) update(rc,M+,R); sumv[u]=sumv[lc]+sumv[rc];
f[u]=f[lc]&&f[rc];
}
}
LL query(int u,int L,int R) {
int lc=u*,rc=u*+;
if(ya<=L && R<=yb) {
return sumv[u];
}
else {
int M=L+(R-L)/;
LL res=;
if(ya<=M) res+=query(lc,L,M);
if(M<yb) res+=query(rc,M+,R);
return res;
}
} int main() {
n=read();
FOR(i,,n) a[i]=read();
build(,,n);
m=read();
int w;
while(m--) {
w=read(),ya=read(),yb=read();
if(ya>yb) swap(ya,yb);
if(w) printf("%lld\n",query(,,n));
else update(,,n);
}
return ;
}

codevs2492 上帝造题的七分钟 2的更多相关文章

  1. codevs2492上帝造题的七分钟 2(线段树)

    /* 区间修改 区间查询 可以用线段树搞 但是一般的标记下放对这个题好像不合适 只能改叶子 然后更新父亲(虽然跑的有点慢) 小优化:如果某个点是1 就不用再开方了 所以搞一个f[i]标记 i 这个点还 ...

  2. CodeVS2492 上帝造题的七分钟2(树状数组+并查集)

    传送门 树状数组模板题.注意优化,假设某个数的值已经是1了的话.那么我们以后就不用对他进行操作了,这个能够用并查集实现. 这道题还有个坑的地方,给出查询区间端点的a,b,有可能a>b. #inc ...

  3. C++之路进阶——codevs2492(上帝造题的七分钟 2)

    2492 上帝造题的七分钟 2  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master    题目描述 Description XLk觉得<上帝造题的七分钟&g ...

  4. 【BZOJ3211&3038】花神游历各国&上帝造题的七分钟2(CodeVS)

    Description   Input   Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 4 1 100 5 5 5 1 1 2 2 1 2 1 1 2 2 ...

  5. 【BZOJ】3038: 上帝造题的七分钟2(线段树+暴力)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=3038 这题我就有得吐槽了,先是线段树更新写错,然后不知哪没pushup导致te,精度问题sq ...

  6. BZOJ3132: 上帝造题的七分钟

    3132: 上帝造题的七分钟 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 483  Solved: 222[Submit][Status] Desc ...

  7. tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树

    P1716 - 上帝造题的七分钟 From Riatre    Normal (OI)总时限:50s    内存限制:128MB    代码长度限制:64KB 背景 Background 裸体就意味着 ...

  8. 「Poetize4」上帝造题的七分钟2

    描述 Description "第一分钟,X说,要有数列,于是便给定了一个正整数数列.第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作.第三分钟,k说,要能查询, ...

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

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

随机推荐

  1. 正则表达式匹配(node.js)

    参考文档如下: http://blog.csdn.net/huiguixian/article/details/6131048 http://www.91xueke.com/2013/04/05/30 ...

  2. PHP环境搭建所遇到的问题

    下午学校的机房搭建PHP组合包appserv开发环境的时候是没有任何问题的,但是到了自己的电脑上以后下砸的32位appserve一直无法正常由浏览器的localhos或者127.0.0.1 进入其ap ...

  3. tomcat 正常启动,无法访问。且项目启动无问题。。。的解决办法。。

    Eclipes解决方法: 1.右击项目,选择propreties选项 2.在弹出的首选项窗口的左侧选择“Web Project Settings” 3.修改context root:输入框,修改成自己 ...

  4. ios 动画效果CATransition笔记

    初学ios开发,很多概念还不清楚,所以只有边学边做例子.又怕学了后面忘了前面,因此用自己的博客来纪录自己的学习历程,也是对自己学习不要懈怠做个监督. 刚学ios做动画效果.因为ios封装得很好,实现i ...

  5. C++ STL的基本基本原理

    STL都是在内存的堆区分配的,但是其析构也是STL帮我们做好的,不用手动去delete. 1.vector 逻辑地址连续的一片内存空间,当空间不足,重新申请新的地址空间,将原有的数据复制过去,而新的地 ...

  6. java中jdk环境配置

    配置java环境,俗称jdk环境 首先进入配置环境的目录下:右键鼠标我的电脑->属性->高级系统设置->环境变量,在对应的"系统变量"框下配置一下变量: 规范的配 ...

  7. Linux内存点滴:用户进程内存空间

    原文出处:PerfGeeks 经常使用top命令了解进程信息,其中包括内存方面的信息.命令top帮助文档是这么解释各个字段的.VIRT , Virtual Image (kb)RES, Residen ...

  8. PAT - 基础 - 最大公约数和最小公倍数

    题目: 本题要求两个给定正整数的最大公约数和最小公倍数. 输入格式: 输入在一行中给出2个正整数M和N(<=1000). 输出格式: 在一行中顺序输出M和N的最大公约数和最小公倍数,两数字间以1 ...

  9. SVN更新失败,提示locked

    使用SVN更新资源时,提示locked,解决方案如下: 首先找到是哪个文件不能进行更新/提交,在本地工作区间中找到这个文件对应的目录,目录里面会有.svn文件夹,这个文件夹默认是隐藏的,需要设置文件夹 ...

  10. 微信开放平台获取component_verify_ticket

    官方文档说明: 在公众号第三方平台创建审核通过后,微信服务器会向其“授权事件接收URL”每隔10分钟定时推送component_verify_ticket.第三方平台方在收到ticket推送后也需进行 ...