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. PHP 通过随机数获得ASCII 值返回字符。

    for($i=0;$i<20;$i++){ $Matrix .= chr(65 + rand(0,26)); }

  2. 推荐Asp.net WebApi入门教程

    Web API 强势入门指南; Web API 入门指南 - 闲话安全; 实例快速上手 -ASP.NET 4.5新特性WebAPI从入门到精通; Asp.net WebApi 项目示例(增删改查).

  3. Typescript 团队合作的利器

    前言 在介绍Typescript 之前,我需要隆重介绍一个人: 安德斯·海尔斯伯格(Anders Hejlsberg,1960.12~),丹麦人,Turbo Pascal编译器的主要作者,Delphi ...

  4. AngularJS+NodeJS环境搭建

    需要安装的软件: node-v0.12.7-x64.msi python-2.7.10.amd64.msi Git-2.5.1-64-bit.exe (注意:Git安装时,需要选择的步骤)  安装位置 ...

  5. pthread_setcanceltype 线程取消

    取消线程: (1)一个线程可以调用pthread_cancel来取消另一个线程.    (2)被取消的线程需要被join来释放资源.    (3)被取消的线程的返回值为PTHREAD_CANCELED ...

  6. js创建对象的三种方法:文本标识法和构造器函数法和返回对象的函数

    文本标识法和定义变量差不多,像这样 var obj = {name:'HanMM','2':'Dali'}; 函数构造器法  先创建一个对象函数 function Obj() { this.addre ...

  7. php基础知识【函数】(6)mysql数据库

    一.连接和关闭 1.mysql_connect('example.com:3307', 'root', '123456') --打开一个到 MySQL 服务器的非永久连接 2.mysql_pconne ...

  8. phpcms 如何获取文章

    请求地址http://127.0.0.1/phpcms/index.php?m=content&c=index&a=show&catid=6&id=8 先来判断地址对应 ...

  9. 基于 libmemcahce 的memcache 操作

    <?php echo '<pre>'; //测试的键值的数量 $count = 30; $mem = create_memcache(); //var_dump($mem->i ...

  10. Python学习的一些好资料

    教程: 1. 廖雪峰的Python教程:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a0 ...