SP2713 GSS4 - Can you answer these queries IV 分块
问题描述
题解
分块,区间开根。
如果一块的最大值是 \(1\) ,那么这个块就不用开根了。
如果最大值不是 \(1\) ,直接暴力开就好了。
\(\mathrm{Code}\)
#include<bits/stdc++.h>
using namespace std;
#define int long long
template <typename Tp>
void read(Tp &x){
	x=0;char ch=1;int fh;
	while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
	if(ch=='-') ch=getchar(),fh=-1;
	else fh=1;
	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	x*=fh;
}
int non;
const int maxn=100007;
int n,cas;
int a[maxn];
int L[maxn],R[maxn],bel[maxn];
int cnt,blo,mx[maxn],sum[maxn];
void reset(){
	memset(mx,0,sizeof(mx));
	memset(sum,0,sizeof(sum));
	memset(L,0,sizeof(L));
	memset(R,0,sizeof(R));
	memset(bel,0,sizeof(bel));
}
void Init(){
	for(int i=1;i<=n;i++) read(a[i]);
}
void change(){
	int x,y;read(x);read(y);//read(non);
	if(x>y) swap(x,y);
	if(bel[x]==bel[y]){
		if(mx[bel[x]]==1) return;
		for(int i=x;i<=y;i++){
			sum[bel[i]]-=a[i];
			a[i]=sqrt((double)a[i]);
			sum[bel[i]]+=a[i];
		}
		mx[bel[x]]=-1;
		for(int i=L[bel[x]];i<=R[bel[x]];i++)
			mx[bel[x]]=max(mx[bel[x]],a[i]);
		return;
	}
	if(mx[bel[x]]!=1){
		for(int i=x;i<=R[bel[x]];i++){
			sum[bel[i]]-=a[i];
			a[i]=sqrt((double)a[i]);
			sum[bel[i]]+=a[i];
		}
		mx[bel[x]]=-1;
		for(int i=L[bel[x]];i<=R[bel[x]];i++){
			mx[bel[x]]=max(mx[bel[x]],a[i]);
		}
	}
	if(mx[bel[y]]!=1){
		for(int i=L[bel[y]];i<=y;i++){
			sum[bel[i]]-=a[i];
			a[i]=sqrt((double)a[i]);
			sum[bel[i]]+=a[i];
		}
		mx[bel[y]]=-1;
		for(int i=L[bel[y]];i<=R[bel[y]];i++){
			mx[bel[y]]=max(mx[bel[y]],a[i]);
		}
	}
	for(int i=bel[x]+1;i<bel[y];i++){
		if(mx[i]==1) continue;
		mx[i]=-1;
		for(int j=L[i];j<=R[i];j++){
			sum[i]-=a[j];
			a[j]=sqrt((double)a[j]);
			sum[i]+=a[j];
			mx[i]=max(mx[i],a[j]);
		}
	}
}
void query(){
	int res=0,x,y;read(x);read(y);//read(non);
	if(x>y) swap(x,y);
	if(bel[x]==bel[y]){
		for(int i=x;i<=y;i++) res+=a[i];
		printf("%lld\n",res);
		return;
	}
	for(int i=x;i<=R[bel[x]];i++) res+=a[i];
	for(int i=L[bel[y]];i<=y;i++) res+=a[i];
	for(int i=bel[x]+1;i<bel[y];i++) res+=sum[i];
	printf("%lld\n",res);
}
void solve(){
	blo=sqrt((double)n);cnt=n/blo;
	cnt=cnt+((n%blo)!=0);
	for(int i=1;i<=cnt;i++){
		L[i]=(i-1)*blo+1,R[i]=i*blo;
	}
	R[cnt]=n;
	for(int i=1;i<=n;i++){
		bel[i]=(i-1)/blo+1;
		sum[bel[i]]+=a[i];
		mx[bel[i]]=max(mx[bel[i]],a[i]);
	}
	int T,op;
//	T=n;
	read(T);
	while(T--){
		read(op);
		if(op==0) change();
		else query();
	}
	puts("");
}
signed main(){
	while((~scanf("%lld",&n))&&n){
		printf("Case #%d:\n",++cas);
		reset();Init();solve();
	}
	return 0;
}
SP2713 GSS4 - Can you answer these queries IV 分块的更多相关文章
- 线段树 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 ... 
- SP2713 GSS4 - Can you answer these queries IV(线段树)
		传送门 解题思路 大概就是一个数很少次数的开方会开到\(1\),而\(1\)开方还是\(1\),所以维护一个和,维护一个开方标记,维护一个区间是否全部为\(1/0\)的标记.然后每次修改时先看是否有全 ... 
- 【SP2713 GSS4 - Can you answer these queries IV】 题解
		题目链接:https://www.luogu.org/problemnew/show/SP2713 真暴力啊. 开方你开就是了,开上6次就都没了. #include <cmath> #in ... 
- SP2713 GSS4 - Can you answer these queries IV
		题目大意 \(n\) 个数,和在\(10^{18}\)范围内. 也就是\(\sum~a_i~\leq~10^{18}\) 现在有两种操作 0 x y 把区间[x,y]内的每个数开方,下取整 1 x y ... 
- 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)
		题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ... 
- GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 (线段树)
		GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 GSS4 - Can you answer these qu ... 
- 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
		题目描述 You are given a sequence \(A\) of \(N(N \leq 100,000)\) positive integers. There sum will be le ... 
- 「SP2713」GSS4 - Can you answer these queries IV
		传送门 Luogu 解题思路 区间开方以及区间求和. 考虑用线段树来做. 开方操作看似没有任何结合律可言,但这题有另外一个性质: 一个数的初始值不超过 \(10^{18}\) ,而这个数被开方6次左右 ... 
随机推荐
- tf.nn.in_top_k的用法
			tf.nn.in_top_k组要是用于计算预测的结果和实际结果的是否相等,返回一个bool类型的张量,tf.nn.in_top_k(prediction, target, K):prediction就 ... 
- Javascript获取元素的xpath
			//获取xpath function readXPath(element) { if (element.id !== "") {//判断id属性,如果这个元素有id,则显 示//* ... 
- 获取input type=file 的文件内容(纯文本)
			一.获取input type=file 的文件内容(纯文本) 1.需求一 通过点击其他事件,来触发 文件选择框(限定格式为 .c 文件),而不是手动鼠标点击触发. [思路:] step1:将 inpu ... 
- Python 函数和类
			python作为一个面向对象的语言,也有类似java等面向对象语言相同的数据结构(class)的定义,和代码块数据结构定义"函数".为了极大可能的简化代码调用逻辑和书写规则,pyt ... 
- 解决测试redis集群时报"java.lang.NumberFormatException: For input string: "7003@17003..7002@17002"等异常
			一.前言 关于redis5.0的集群模式下,通过客户端测试代码调试报"Exception in thread "main" java.lang.NumberFormatE ... 
- 使用C#面向对象实现简易计算器(简单工厂模式)
			操作流程: 1. 新建Operation类 2. 新建OperationAdd类,并继承Operation类 3. 新建OperationSub类,并继承Operation类 4. 新建Operati ... 
- C语言复习上
			通常开始学习C语言的时候,第一句写的就是"helloword" int main(){ printf("hello word"); } 接下来的日子里需要注意的 ... 
- 14. java面向对象 - 基础
			一.面向对象主线 1. Java类及类的成员:属性.方法.构造器.代码块.内部类 2. 面向对象三大特征:封装.继承.多态.(抽象性) 3. 其他关键字:this.super.static.final ... 
- 磕磕绊绊中,使用Git工具完成代码上传
			1.安装Git工具 1)下载并安装Git工具:Git下载地址 安装完成之后,在桌面空白处点击右键,会出现以下选项: 2.初始化环境 1) 在一文件夹中,点击右键,选择上图中的Git Bash Here ... 
- centos7安装服务器之安装禅道
			Centos7下安装禅道 1. 下载禅道的linux版本 我的centos7的版本为:7.7版本 2. 将下载的包上传到centos7服务器上 3. 将禅道压缩包解压到/opt目录下: 4. 启动禅道 ... 
