题意:给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. Sgu149 Computer Network

    Sgu149 Computer Network 题目描述 给你一棵N(N<=10000)个节点的树,求每个点到其他点的最大距离. 不难想到一个节点到其他点的最大距离为:max(以它为根的子树的最 ...

  2. HATEOAS的简单认识

    HATEOAS: 超媒体作为应用程序状态引擎(HATEOAS)是REST应用程序体系结构的一个组件,它将其与其他网络应用程序体系结构区分开来. 使用HATEOAS,客户端与网络应用程序交互,其应用程序 ...

  3. uni-app开发经验分享十六:发布android版App的详细过程

    开发环境 1. Android Studio下载地址:Android Studio官网 OR Android Studio中文社区 2. HBuilderX(开发工具) 3. App离线SDK下载:最 ...

  4. 代理模式详解:静态代理+JDK/CGLIB 动态代理实战

    1. 代理模式 代理模式是一种比较好的理解的设计模式.简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标 ...

  5. Redis集群拆分原则之AKF

    当我们搭建集群的时候,首先要想明白需要解决哪些问题,搞清楚这个之前,想想单节点.单实例.单机有哪些问题? 单点故障 容量有限 可支持的连接有限(性能不足) ...... 为了解决这些问题,我们需要对服 ...

  6. pod资源限制和QoS探索

    简述 默认情况下,k8s不会对pod的资源使用进行限制,也就是说,pod可以无限使用主机的资源,例如CPU.内存等.为了保障k8s整体环境运行的稳定性,一般情况下,建议是对pod的资源使用进行限制,将 ...

  7. idea一定要做的配置

    自动编译开关 忽略大小写开关 IDEA默认匹配大小写,如果你开了这个开关,你无论输入String或者string都会出现代码提示或者智能补充 智能导包开关 两个选项勾上:自动导入不明确的结构.智能优化 ...

  8. Web信息收集之搜索引擎-GoogleHacking

    Web信息收集之搜索引擎-GoogleHacking 一.信息收集概述 二.Google Hacking 2.1 site 2.2 filetype 2.3 inurl 2.4 intitle 2.5 ...

  9. Spark Streaming状态管理函数updateStateByKey和mapWithState

    Spark Streaming状态管理函数updateStateByKey和mapWithState 一.状态管理函数 二.mapWithState 2.1关于mapWithState 2.2mapW ...

  10. typedef void (*sighandler_t)(int);

    typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); ---------- ...