BZOJ3211 花神游历各国(分块 区间开根号)
题意:给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 花神游历各国(分块 区间开根号)的更多相关文章
- BZOJ3211花神游历各国
BZOJ3211花神游历各国 BZOJ luogu 分块 记一个all表示该块是否全部<=1,如果all不为真就暴力修改 因为一个数被开根的次数不多,即使\(10^{12}\)只要开根6次也会变 ...
- bzoj3211花神游历各国&&bzoj3038上帝造题的七分钟2*
bzoj3211花神游历各国 题意: n个数的序列,m个操作,操作两种:区间开根(向下取整)和区间求和.n≤100000,m≤200000,序列中的数非负且≤109. 题解: 一个≤109的数开6次根 ...
- bzoj3211 花神游历各国 线段树,势能分析
[bzoj3211]花神游历各国 2014年3月17日2,7230 Description Input Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input ...
- BZOJ-3211花神游历各国 并查集+树状数组
一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MB Subm ...
- bzoj3211花神游历各国 线段树
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 4252 Solved: 1547[Submit][Status][Discu ...
- bzoj3211: 花神游历各国(线段树) 同codevs2492
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 3628 Solved: 1326[Submit][Status][Discu ...
- BZOJ3211: 花神游历各国(线段树)
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 5692 Solved: 2114[Submit][Status][Discu ...
- [BZOJ3211]花神游历各国&&[BZOJ3038] 上帝造题的七分钟2 树状数组+并查集
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 4057 Solved: 1480[Submit][Status][Discu ...
- luogu P4145 上帝造题的七分钟2 / 花神游历各国 维护区间和&&区间开根号
因为开根号能使数字减小得非常快 所以开不了几次(6次?)很大的数就会变成1..... 所以我们可以维护区间最大值,若最大值>1,则继续递归子树,暴力修改叶节点,否则直接return (好像也可以 ...
- [BZOJ3211]花神游历各国(线段树+区间开根)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3211 分析: 区间开根是没法区间合并的. 但是注意到10^9开根开个5次就变成1了…… ...
随机推荐
- python生成器 递归
生成器 生成器:只要函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器 生成器就是迭代器 yield的功能 1.yield为我们提供了一种自定义迭 ...
- 今天聊点干货—关于CSS样式来源
样式来源 CSS样式共有5个来源,它们分别是\(\color{#FF3030}{浏览器默认样式}\).\(\color{#FF3030}{用户样式}\).\(\color{#FF3030}{链接样式} ...
- ldf和mdf文件怎么还原到sqlserver数据库
1.把mdf文件和ldf文件拷贝到数据库的默认路径C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA里:2.在sq ...
- Redis 实战 —— 09. 实现任务队列、消息拉取和文件分发
任务队列 P133 通过将待执行任务的相关信息放入队列里面,并在之后对队列进行处理,可以推迟执行那些耗时对操作,这种将工作交给任务处理器来执行对做法被称为任务队列 (task queue) . P13 ...
- Communicating sequential processes CSP 通信顺序进程 CSP writing to a file by name (process, Erlang) vs. writing to a file descriptor (channel, Go)
the-way-to-go_ZH_CN/01.2.md at master · Unknwon/the-way-to-go_ZH_CN https://github.com/Unknwon/the-w ...
- LOJ10082
题目描述 原题来自:Centrual Europe 2005 我们有N个字符串,每个字符串都是由 a 至 z 的小写英文字母组成的.如果字符串A的结尾两个字符刚好与字符串B的开头两个字符匹配,那么我们 ...
- Python3 如何查看内置函数都有哪些?
数据科学交流群,群号:189158789,欢迎各位对数据科学感兴趣的小伙伴的加入! 上代码: 1 import builtins 2 num = len(dir(builtins)) 3 print( ...
- Git基本概念,流程,分支,标签及常用命令
Git基本概念,流程,分支,标签及常用命令 Git一张图 Git基本概念 仓库(Repository) 分支(Branch) Git工作流程 Git分支管理(branch) 列出分支 删除分支 分支合 ...
- linux shell判断文件,目录是否存在或者具有权限
在linux中判断文件,目录是否存在或则具有的权限,根据最近的学习以及网上的资料,进行了以下的总结: #!/bin/sh myPath="/var/log/httpd/" myFi ...
- python--基础3(流程语句)
资源池 链接:https://pan.baidu.com/s/1OGq0GaVcAuYEk4F71v0RWw 提取码:h2sd 本章内容: if判断语句 for循环语句 while循环语句 break ...