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. android 数字键盘制作

    //布局相关<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android ...

  2. ASP.NET实现二级域名(多用户,多商店)

    本人所了解有两种方案,可能还有其的方式,希望大家多多讨论!  基本思路:  1. 域名支持泛解析,即是指:把A记录 *.域名.com 解析到服务器IP,服务器IIS中做绑定,绑定时主机头为空;  2. ...

  3. Java循环性能随笔

    for iterator做迭代循环性能最好 然后是foreach 然后是提前声明好变量的for循环 最后是每次都要计算集合size的for       package test;   import j ...

  4. Codeforces 193D Two Segments 解题报告

    先是在蓝桥杯的网站上看到一道题: 给出1~n的一个排列,求出区间内所有数是连续自然数的区间的个数.n<=50000. 由于数据较弱,即使用O(N^2)的算法也能拿到满分. 于是在CF上发现了这一 ...

  5. js定位navigator.geolocation

    一.简介 html5为window.navigator提供了geolocation属性,用于获取基于浏览器的当前用户地理位置. window.navigator.geolocation提供了3个方法分 ...

  6. JavaScript解析机制

    JavaScript是一种解释型语言,按照<script>块儿来预编译和执行. JavaScript解释器在预编译阶段,先预声明变量,再预声明函数.在执行阶段,进行变量赋值,和函数执行. ...

  7. emmet插件的导入与实用

    http://jingyan.baidu.com/article/ff4116259b057c12e48237b8.html http://www.iteye.com/news/27580 分享htm ...

  8. IOS--UIButton的使用方法

    设置UIButton的文字显示位置.字体的大小.字体的颜色 分类: iphone界面详解2012-12-21 14:32 27269人阅读 评论(2) 收藏 举报 btn.frame = CGRect ...

  9. 转:2014 年 15 款新评定的最佳 PHP 框架

    原文来自于:http://blog.jobbole.com/59999/ 原文出处: codegeekz   译文出处:oschina   欢迎分享原创到伯乐头条 通常,框架都会被认为是帮助开发者快速 ...

  10. 开发人员应关注的20个jQuery网站/博客

    http://blog.jobbole.com/1466/ 2.  10个优秀的移动Web应用开发框架 http://blog.jobbole.com/1436/ 3.  介绍jQ Mobile ht ...