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. Canvas模糊化处理图片、毛玻璃处理图片之stackblur.js

    Canvas实现毛玻璃效果解决方式1:使用stackblur.js 在Android系统中实现图片的毛玻璃效果比较好用的类库是:Android StackBlur 官方Git地址:https://gi ...

  2. Java开发工程师必会做试题

    一.单选题     (共19道题,每题5分) 1.下面有关java的一些细节问题,描述错误的是? A.构造方法不需要同步化 B.一个子类不可以覆盖掉父类的同步方法 C.定义在接口中的方法默认是publ ...

  3. jsp-文件的上传(转).

    该程序的主要代码,我引用网友的,并做了一些改进.上这个帖子的原因之一,是为了修正之前自己的一些误解. 概述: 一些网友,包括我,也曾经试图通过 input type 为 file的控件,获取其文件的完 ...

  4. JavaScript Comparison and Logical Operators

    Ref:http://www.w3schools.com/js/js_comparisons.asp var r = 1; var result = r || 2; console.log(resul ...

  5. 比较两份文件的异同-beyond compare

    比较两份文件的异同-beyond compare 今天又学到一个知识,比较两次文件的 异同.  哈哈 谢谢领导

  6. PHP算法 《图》 之 理论基础

    转载自:http://www.cnblogs.com/skywang12345/p/3691463.html Ⅰ 图的基本概念 1. 图的定义 定义:图(graph)是由一些点(vertex)和这些点 ...

  7. set,multiset容器类型

    set和multiset会根据特定的排序准则,自动将元素排序.两者不同处在于multiset允许元素重复而set不允许. 一.集和多集(set 和multiset 容器类) 在使用set和multis ...

  8. jQuery慢慢啃之文档处理(五)

    1.append(content|fn)//向每个匹配的元素内部追加内容. $("p").append("<b>Hello</b>"); ...

  9. prototype/constructor/__proto__之constructor。

    1.constructor的字面意思就是构造.它是对象的一个属性,它对应的值是该对象的“构造者” //一.构造函数实例化的对象的constructor function Cmf(n,m){ this. ...

  10. 实例:用jQuery实现垂直和水平下拉 菜单

    主要是利用jQuery来实现垂直菜单和水平菜单.实现效果如图: 第一步,创建一个HTML文件,如图,包含两个ul.当然把jquery库也引入进去了. <!DOCTYPE html> < ...