题意:给n个数,可以进行两种操作:给区间[l,r]每个数开方向下取整;算区间[l,r]的和。

思路:我们可以知道,一个数一直开方下去,就会变成0或者1,然后就不会变了。那么当一个区间只剩0或1时,就不用进行操作了。那么直接分块,然后搞一个flag判断一下是否变成0。稍微优化一下。

代码:

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 10;
const int M = maxn * 30;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int belong[maxn], block;
int flag[maxn];
ll sum[maxn];
ll a[maxn];
struct Block{
int l, r;
}b[maxn];
void change(int l, int r){
int bl = belong[l], br = belong[r];
if(bl == br){
if(!flag[bl]){
for(int i = l; i <= r; i++){
sum[bl] -= a[i];
a[i] = (int)sqrt(a[i]);
sum[bl] += a[i];
}
flag[bl] = 1;
for(int j = b[bl].l; j <= b[bl].r; j++){
if(a[j] > 1){
flag[bl] = 0;
break;
}
}
}
}
else{
if(!flag[bl]){
for(int i = l; i <= b[bl].r; i++){
sum[bl] -= a[i];
a[i] = (int)sqrt(a[i]);
sum[bl] += a[i];
}
flag[bl] = 1;
for(int j = b[bl].l; j <= b[bl].r; j++){
if(a[j] > 1){
flag[bl] = 0;
break;
}
}
}
for(int i = bl + 1; i <= br - 1; i++){
if(!flag[i]){
sum[i] = 0;
flag[i] = 1;
for(int j = b[i].l; j <= b[i].r; j++){
a[j] = (int)sqrt(a[j]);
sum[i] += a[j];
if(a[j] > 1) flag[i] = 0;
}
}
}
if(!flag[br]){
for(int i = b[br].l; i <= r; i++){
sum[br] -= a[i];
a[i] = (int)sqrt(a[i]);
sum[br] += a[i];
}
flag[br] = 1;
for(int j = b[br].l; j <= b[br].r; j++){
if(a[j] > 1){
flag[br] = 0;
break;
}
}
}
}
} ll query(int l, int r){
int bl = belong[l], br = belong[r];
ll ans = 0;
if(bl == br){
for(int i = l; i <= r; i++){
ans += a[i];
}
}
else{
for(int i = l; i <= b[bl].r; i++){
ans += a[i];
}
for(int i = bl + 1; i <= br - 1; i++){
ans += sum[i];
}
for(int i = b[br].l; i <= r; i++){
ans += a[i];
}
}
return ans;
}
int main(){
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%lld", &a[i]);
}
block = sqrt(n);
for(int i = 1; i <= n; i++){
belong[i] = (i - 1) / block + 1;
}
for(int i = 1; i <= belong[n]; i++){
b[i].l = (i - 1) * block + 1;
b[i].r = min(n, b[i].l + block - 1);
sum[i] = flag[i] = 0;
for(int j = b[i].l; j <= b[i].r; j++) sum[i] += a[j];
}
int m;
scanf("%d", &m);
for(int i = 1; i <= m; i++){
int o, l, r;
int c;
scanf("%d%d%d", &o, &l, &r);
if(o == 2){
change(l, r);
}
else{
printf("%lld\n", query(l, r));
}
}
return 0;
}

BZOJ3211 花神游历各国(分块 区间开根号)的更多相关文章

  1. BZOJ3211花神游历各国

    BZOJ3211花神游历各国 BZOJ luogu 分块 记一个all表示该块是否全部<=1,如果all不为真就暴力修改 因为一个数被开根的次数不多,即使\(10^{12}\)只要开根6次也会变 ...

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

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

  3. bzoj3211 花神游历各国 线段树,势能分析

    [bzoj3211]花神游历各国 2014年3月17日2,7230 Description   Input   Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input ...

  4. BZOJ-3211花神游历各国 并查集+树状数组

    一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MB Subm ...

  5. bzoj3211花神游历各国 线段树

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

  6. bzoj3211: 花神游历各国(线段树) 同codevs2492

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

  7. BZOJ3211: 花神游历各国(线段树)

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

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

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

  9. luogu P4145 上帝造题的七分钟2 / 花神游历各国 维护区间和&&区间开根号

    因为开根号能使数字减小得非常快 所以开不了几次(6次?)很大的数就会变成1..... 所以我们可以维护区间最大值,若最大值>1,则继续递归子树,暴力修改叶节点,否则直接return (好像也可以 ...

  10. [BZOJ3211]花神游历各国(线段树+区间开根)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3211 分析: 区间开根是没法区间合并的. 但是注意到10^9开根开个5次就变成1了…… ...

随机推荐

  1. 写给 Linux 初学者的一封信

    大家好,我是肖邦. 这篇文章是写给 Linux 初学者的,我会分享一些作为初学者应该知道的一些东西,这些内容都是本人从事 Linux 开发工作多年的心得体会,相信会对初学者有所帮助.如果你是 Linu ...

  2. Python内存浅析

    Python内存分析 内存机制 转述:内存中的堆栈和数据结构堆栈不是一个概念,可以说内存中的堆栈是真实存在的物理区,数据结构中的堆栈是抽象的数据存储结构. Python的内存机制和Java差不多,分为 ...

  3. C#高级编程第11版 - 第九章 索引

    [1]9.1 System.String 类 String类中关键的方法.如替换,比较等. [2]9.1.1 构建字符串 1.String类依然有一个缺点:因为它是不可变的数据类型,这意味当你初始化一 ...

  4. 页面切换提速30%!京东商城APP首屏耗时监控及优化实践

    https://mp.weixin.qq.com/s/vIG_x1MWC33HKV1GxalVHg 原创 平台研发朱跃棕等 京东零售技术 2020-12-09 网络接口请求可以从接口结构合理性及多接口 ...

  5. 线上nginx的一次“no live upstreams while connecting to upstream ”分析

    线上nginx的一次"no live upstreams while connecting to upstream "分析 线上nginx的一次"no live upst ...

  6. slice 切片实现 Slice object interface

    1.Python切片对象可以为任意类型 https://github.com/python/cpython/blob/master/Include/sliceobject.h /* Slice obj ...

  7. 博客-livevent-stl-cpp-nginx

    https://blog.csdn.net/move_now/article/category/6420121

  8. Redis 常见问题总结

    1. 简单介绍一下 Redis 呗! 简单来说 Redis 就是一个使用 C 语言开发的数据库,不过与传统数据库不同的是 Redis 的数据是存在内存中的 ,也就是它是内存数据库,所以读写速度非常快, ...

  9. NodeJS入门学习教程

    一.概念 1.什么是nodejs Node.js是JavaScript 运行时环境,通俗易懂的讲,Node.js是JavaScript的运行平台 Node.js既不是语言,也不是框架,它是一个平台 2 ...

  10. Chrome标签整理

    程序人生 设计素材类网站 关于生活 求职相关网站 Web前端 科技新闻相关网站 优秀资源内含丰富学习资料 项目实例视频资料等 面试简历相关 适合初学者自学的编程网站 国内优秀博客 由于平时经常浏览一些 ...