GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 (线段树)
GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国
GSS4 - Can you answer these queries IV
题目链接:https://www.luogu.org/problemnew/show/SP2713
线段树经典题目,然而被我用分块A了.
对于区间开根号,\(1e18\)最多会被开\(6\)次就会成为\(1\),成为\(1\)后,再开根号也是\(1\),0开根号也是0,线段树(分块)维护区间所有的数是否全部小于等于1,如果不是,就暴力更新,如果是,那就不要更新这个区间.
时间复杂度\(O(\sqrt n * n)\)
分块CODE:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define ll long long
const int maxN = 100000 + 7;
ll a[maxN];
bool is_sqrt[maxN];
int L[maxN],R[maxN],belong[maxN];
ll sum[maxN];
int num[maxN];
inline ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
return x * f;
}
ll Query(int l,int r) {
int b_l = belong[l],b_r = belong[r];
ll ans = 0;
if(b_l == b_r) {
for(int i = l;i <= r;++ i)
ans += a[i];
return ans;
}
for(int i = b_l + 1;i < b_r;++ i) ans += sum[i];
for(int i = l;i <= R[b_l];++ i) ans += a[i];
for(int i = L[b_r];i <= r;++ i) ans += a[i];
return ans;
}
void Inter_sqrt(int l,int r) {
int b_l = belong[l],b_r = belong[r];
if(b_l == b_r) {
if(is_sqrt[b_l]) return;
for(int i = l;i <= r;++ i) {
if(a[i] == 1) continue;
sum[b_l] -=a[i];
a[i] = sqrt(a[i]);
sum[b_l] += a[i];
if(a[i] == 1) num[b_l] ++;
}
if(num[b_l] == R[b_l] - L[b_l] + 1) is_sqrt[b_l] = true;
return;
}
for(int i = b_l + 1;i < b_r;++ i) {
if(is_sqrt[i]) continue;
for(int j = L[i];j <= R[i];++ j) {
if(a[j] == 1) continue;
sum[i] -=a[j];
a[j] = sqrt(a[j]);
sum[i] += a[j];
if(a[j] == 1) num[i] ++;
}
if(num[i] == R[i] - L[i] + 1) is_sqrt[i] = true;
}
for(int i = l;i <= R[b_l];++ i) {
if(a[i] == 1) continue;
sum[b_l] -=a[i];
a[i] = sqrt(a[i]);
sum[b_l] += a[i];
if(a[i] == 1) num[b_l] ++;
}
if(num[b_l] == R[b_l] - L[b_l] + 1) is_sqrt[b_l] = true;
for(int i = L[b_r];i <= r;++ i) {
if(a[i] == 1) continue;
sum[b_r] -=a[i];
a[i] = sqrt(a[i]);
sum[b_r] += a[i];
if(a[i] == 1) num[b_r] ++;
}
if(num[b_r] == R[b_r] - L[b_r] + 1) is_sqrt[b_r] = true;
}
int main() {
int tot = 0;
int n;
while(scanf("%d",&n) == 1) {
printf("Case #%d:\n",++ tot);
memset(num,0,sizeof(num));
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
memset(sum,0,sizeof(sum));
memset(is_sqrt,0,sizeof(is_sqrt));
int q = sqrt(n);
for(int i = 1;i <= n;++ i)
a[i] = read();
for(int i = 1;i <= n;++ i){
belong[i] = i / q + 1;
sum[belong[i]] += a[i];
if(a[i] == 1) num[belong[i]] ++;
}
for(int i = 1;i <= n;++ i) R[belong[i]] = i;
for(int i = n;i >= 1;-- i) L[belong[i]] = i;
int m = read();
int opt,l,r;
while(m --) {
opt = read();l = read();r = read();
if(l > r) std::swap(l,r);
if(opt) printf("%lld\n",Query(l,r));
else Inter_sqrt(l,r);
}
}
return 0;
}
luogu4145上帝造题的七分钟2 / 花神游历各国
用分块很难水过,我们用线段树维护区间最大值即可.
线段树CODE:
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#define max(a,b) a > b ? a : b
#define ll long long
const ll maxN = 100000 + 7;
using namespace std;
struct Node{
ll l,r;
ll sum;
ll maxx;
}tree[maxN << 2];
ll a[maxN];
void swap(ll &a,ll &b) {
ll k = b;
b = a;
a = k;
}
inline ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
return x * f;
}
void updata(ll now) {
tree[now].sum = tree[now << 1].sum + tree[now << 1 | 1].sum;
tree[now].maxx = max(tree[now << 1 | 1].maxx,tree[now << 1].maxx);
}
void build(ll l,ll r,ll now) {
tree[now].l = l;
tree[now].r = r;
if(l == r) {
tree[now].sum = a[l];
tree[now].maxx = a[l];
return ;
}
ll mid = (l + r) >> 1;
build(l,mid,now << 1);
build(mid + 1,r,now << 1 | 1);
updata(now);
}
ll Query(ll l,ll r,ll now) {
if(tree[now].l >= l && tree[now].r <= r) return tree[now].sum;
ll mid = (tree[now].l + tree[now].r) >> 1;
ll sum = 0;
if(l <= mid) sum += Query(l,r,now << 1);
if(r > mid) sum += Query(l,r,now << 1 | 1);
return sum;
}
void work(ll now) {
if(tree[now].l == tree[now].r) {
ll L = tree[now].l;
a[L] = sqrt(a[L]);
tree[now].sum = a[L];
tree[now].maxx = a[L];
return;
}
if(tree[now << 1].maxx > 1) work(now << 1);
if(tree[now << 1 | 1].maxx > 1) work(now << 1 | 1);
updata(now);
return ;
}
void Inter_sqrt(ll l,ll r,ll now) {
if(tree[now].l >= l && tree[now].r <= r) {
if( tree[now].maxx > 1 ) work(now);
return ;
}
ll mid = (tree[now].l + tree[now].r) >> 1;
if(l <= mid) Inter_sqrt(l,r,now << 1);
if(r > mid) Inter_sqrt(l,r,now << 1 | 1);
updata(now);
return;
}
int main() {
ll n = read();
for(ll i = 1;i <= n;++ i)
a[i] = read();
build(1,n,1);
ll m = read();
ll opt,l,r;
while(m --) {
opt = read();l = read();r = read();
if(l > r)swap(l,r);
if(opt == 1) printf("%lld\n",Query(l,r,1));
else Inter_sqrt(l,r,1);
}
return 0;
}
/*
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
*/
GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 (线段树)的更多相关文章
- 线段树 SP2713 GSS4 - Can you answer these queries IV暨 【洛谷P4145】 上帝造题的七分钟2 / 花神游历各国
SP2713 GSS4 - Can you answer these queries IV 「题意」: n 个数,每个数在\(10^{18}\) 范围内. 现在有「两种」操作 0 x y把区间\([x ...
- 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- 上帝造题的七分钟2/花神游历各国/GSS4 线段树维护区间开方 By cellur925
题目传送门 或者 另一个传送门 询问区间和都好说.但是开方?? 其实是这样的,一个数(1e9)以内连续开方6次就会变成1,于是我们就可在开方操作上进行暴力修改.暴力修改的意思其实也就是找到叶子节点进行 ...
- 【luogu4145】上帝造题的七分钟2 / 花神游历各国--区间开根-线段树
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- luogu4145 上帝造题的七分钟2 (线段树)
题意:给一个数列,维护两个操作,区间开根号.询问区间和 注意到1e12开根号六次后就变成1,而且根号1等于1 也就是说,就算我们用单点修改,只要跳过1,那么修改的次数最多也就是6n 那么维护一个区间最 ...
- 题解【luogu4145 上帝造题的七分钟2(花神游历各国)】
题目大意: 一个序列,支持区间开方与求和操作. 算法:线段树实现开方修改与区间求和 分析: 显然,这道题的求和操作可以用线段树来维护 但是如何来实现区间开方呢 大家有没有这样的经历:玩计算器的时候,把 ...
- GSS4 - Can you answer these queries IV(线段树懒操作)
GSS4 - Can you answer these queries IV(线段树懒操作) 标签: 线段树 题目链接 Description recursion有一个正整数序列a[n].现在recu ...
- SP2713 GSS4 - Can you answer these queries IV(线段树)
传送门 解题思路 大概就是一个数很少次数的开方会开到\(1\),而\(1\)开方还是\(1\),所以维护一个和,维护一个开方标记,维护一个区间是否全部为\(1/0\)的标记.然后每次修改时先看是否有全 ...
- SPOJ GSS4 Can you answer these queries IV
Time Limit: 500MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description You are g ...
随机推荐
- 笔记-JavaWeb学习之旅10
Servlet server applet运行在服务器端的小程序,servlet就是一个接口,定义了Java类被浏览器访问到的规则(Java类重写这个接口,就可以被浏览器(tomcat)识别) Ser ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Session常用方法
● public Object getAttribute(String name) 该方法返回在该session会话中具有指定名称的对象,如果没有指定名称的对象,则返回null. ● public ...
- 在mpvue框架中使用Vant WeappUI组件库的注意事项
1如何引入组件库 有两种方法 1 npm下载 2 下载代码,下面介绍第二种方法. 在gitHub上, 链接如下 https://github.com/youzan/vant-weapp 首先在自己项目 ...
- 调用Web API将文件上传到服务器的方法(.Net Core)
最近遇到一个将Excel通过Web API存到服务器的问题,其中涉及到Excel的读取.调用API.Web API怎么进行接收. 一. Excel的读取.调用API Excel读取以及调用API的代 ...
- SVN有任何胜过git的地方吗?
SVN有任何胜过git的地方吗? 好的技术问题通常会引出技术专家们依据经验得出的深层次的观点.但对于这样的问题的答案也很容易演变成完全基于个人喜好的情绪倾泄,而不是根据事实.标准和具体的专业知识.就比 ...
- java中数据的存放位置
引用自java编程思想四----2.2.1 程序运行时,我们最好对数据保存到什么地方做到心中有数.特别要注意的是内存的分配.有六个地方都可以保存数据:(1) 寄存器.这是最快的保存区域,因为它位于和其 ...
- [筆記]catalan卡特蘭數
前言:希望自己每個星期能發一篇文章,提升一下寫文章的能力?雖然對語文作文毫無幫助但是總比玩遊戲強 所以不務正業的東西就不放在首頁了,有興趣的可以點分類去看 來源:https://www.cnblogs ...
- Jasper_crosstab_headerPosition_columngroup header position config - (headerPosition="Stretch")
i.e <columnGroup name="column11" height="20" totalPosition="Start" ...
- B. Apple Tree 暴力 + 数学
http://codeforces.com/problemset/problem/348/B 注意到如果顶点的数值确定了,那么它分下去的个数也就确定了,那么可以暴力枚举顶点的数值. 顶点的数值是和LC ...
- asp.net 图表
感谢csdn深南大道,文章转自http://blog.csdn.net/smartsmile2012/article/details/17356673 前台代码 <div> <asp ...