Can you answer these queries? (HDU4027)(线段树,区间操作)+剪枝

点击这里送你到杭电去answer the queries

Can you answer these queries?

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 31873    Accepted Submission(s): 7608


 

Problem Description

A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of our secret weapon, it could decrease the endurance of a consecutive part of battleships by make their endurance to the square root of it original value of endurance. During the series of attack of our secret weapon, the commander wants to evaluate the effect of the weapon, so he asks you for help.
You are asked to answer the queries that the sum of the endurance of a consecutive part of the battleship line.

Notice that the square root operation should be rounded down to integer.//平方根要四舍五入

 

Input

The input contains several test cases, terminated by EOF.
  For each test case, the first line contains a single integer N, denoting there are N battleships of evil in a line. (1 <= N <= 100000)
  The second line contains N integers Ei, indicating the endurance value of each battleship from the beginning of the line to the end. You can assume that the sum of all endurance value is less than 263.
  The next line contains an integer M, denoting the number of actions and queries. (1 <= M <= 100000)
  For the following M lines, each line contains three integers T, X and Y. The T=0 denoting the action of the secret weapon, which will decrease the endurance value of the battleships between the X-th and Y-th battleship, inclusive. The T=1 denoting the query of the commander which ask for the sum of the endurance value of the battleship between X-th and Y-th, inclusive.

 

Output

For each test case, print the case number at the first line. Then print one line for each query. And remember follow a blank line after each test case.

 

Sample Input

 

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

 

Sample Output

 

Case #1:

19

7

6

 

关于这道题的题意先说一下吧,让你去摧毁战舰,1指令是让你汇报地方区间【】的战舰战斗力之和,0指令是让你去降低区间【】范围内敌方战舰的战斗力,每一次降为其原来的sqrt(),我的第一想法就是区间修改,区间求和,上来就噼里啪啦的一顿敲,马上弄完的时候突然意识到,woc!!!平方根好像不满足分配率,也就是说不能像加法减法最值那样进行集体操作,要了老命了,我就只能试试单点操作喽,又是一顿噼里啪啦,给我TLE了,本以为是哪里写错了,瞄了好多眼,愣是找到致命的错误。。。

昨天晚上一共做了两个题,都给TLE了,还都没改出来,难受啊。。。晚上回宿舍的时候听舍友给我说,需要剪枝 ,因为一个int 型的数最多开七八次根号就会很接近1了,这时候无论怎么开根号结果都一样,然后就是疯狂地浪费时间~~~仔细想想好像是这样啊, 那么然后的任务就是找到内部元素sqrt()等于1的区间进行删除,即不用再更新sqrt,直接return 就ojbk,他用的是区间长度等于其区间数值和的思想,舍友tql   日常膜拜  Orz

今天早上吃饭的时候突然灵光一闪,给他个标记不就完了嘛,然后又是万般调试,把所有的坑都遍历的一遍 ~_~  终于皇天不负有心人,把他给AC了,可能我上辈子就是一棵线段树,太NAN了。。。然鹅心里还没点  B Tree。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int mm=1e5+5;
#define ll long long 
struct node{
	int l,r;
	ll sum;
	int flag;//标记sqrt是否为 1 
//	ll lazy;  
}pp[mm<<2];

ll a[mm];
ll res;

void up(int k){
	pp[k].sum=pp[k<<1].sum+pp[k<<1|1].sum; 
	pp[k].flag=pp[k<<1].flag&&pp[k<<1|1].flag;//整个区间的flag为 1才 能合并  
} 

void build(int k,int l,int r){
	pp[k].l=l;
	pp[k].r=r;
	pp[k].flag=0;
	if(l==r){
		pp[k].sum=a[l];
		if(a[l]<=1)
			pp[k].flag=1;// 
		return ;
	}
	int mid=(r+l)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	up(k);
}

//void pd(int k){
//	if(pp[k].lazy==0)
//		return ;
//	pp[k<<1].sum=(pp[k<<1].r-pp[k<<1].l+1)*pp[k].lazy;
//	pp[k<<1|1].sum=(pp[k<<1|1].r-pp[k<<1|1].l+1)*pp[k].lazy;
//	pp[k<<1|1].lazy=pp[k].lazy;
//	pp[k<<1].lazy=pp[k].lazy;
//	pp[k].lazy=0;
//}

void change(int k,int l,int r){
	if(pp[k].flag==1)
		return; 
	//pd(k);
	if(pp[k].l==pp[k].r){
		pp[k].sum=(ll)sqrt(pp[k].sum*1.0);//注意让平方根四舍五入的方法 
		if(pp[k].sum<=1)
			pp[k].flag=1;//随时更新 
		return ; 
	}
	int mid=(pp[k].l+pp[k].r)>>1;
//	if(r>mid)change(k<<1|1,l,r);
//	if(l<=mid)change(k<<1,l,r);
	if(mid>=r)change(k<<1,l,r);// 
	else if(mid<l)change(k<<1|1,l,r);
	else {
		change(k<<1,l,mid);
		change(k<<1|1,mid+1,r);
	}
	up(k);
}

void query(int k,int l,int r){
	if(pp[k].l==l&&pp[k].r==r){
		res+=pp[k].sum;
		return ;
	}
	if(pp[k].l==pp[k].r)
		return ;
	//pd(k);
	int mid=(pp[k].l+pp[k].r)>>1;
//	if(r>mid)query(k<<1|1,l,r);
//	if(l<=mid)query(k<<1,l,r);
	if(mid>=r)query(k<<1,l,r);
	else if(mid<l)query(k<<1|1,l,r);
	else {
		query(k<<1,l,mid);
		query(k<<1|1,mid+1,r);
	}
}

int main()
{
	int n,m,test=1;
	while(scanf("%d",&n)!=EOF){
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		build(1,1,n);
		printf("Case #%d:\n",test++);
		scanf("%d",&m);
		int op,x,y;
		while(m--){
			scanf("%d%d%d",&op,&x,&y);
			if(x>y)swap(x,y);//这是个大坑  
			if(op==0)change(1,x,y);
			else {
				res=0;
				query(1,x,y);
				printf("%lld\n",res);
			}
		}
		printf("\n");
	}
	return 0;
 } 

 

 

主要内容:本文详细介绍了一种QRBiLSTM(分位数回归双向长短期记忆网络)的时间序列区间预测方法。首先介绍了项目背景以及模型的优势,比如能够有效利用双向的信息,并对未来的趋势上限和下限做出估计。接着从数据生成出发讲述了具体的代码操作过程:数据预处理,搭建模型,进行训练,并最终可视化预测结果与计算分位数回归的边界线。提供的示例代码可以完全运行并且包含了数据生成环节,便于新手快速上手,深入学习。此外还指出了模型未来发展的方向,例如加入额外的输入特性和改善超参数配置等途径提高模型的表现。文中强调了时间序列的标准化和平稳检验,在样本划分阶段需要按时间序列顺序进行划分,并在训练阶段采取合适的手段预防过度拟合发生。 适合人群:对于希望学习和应用双向长短时记忆网络解决时序数据预测的初学者和具有一定基础的研究人员。尤其适用于有金融数据分析需求、需要做多一步或多步预测任务的从业者。 使用场景及目标:应用于金融市场波动预报、天气状况变化预测或是物流管理等多个领域内的决策支持。主要目的在于不仅能够提供精确的数值预计还能描绘出相应的区间概率图以增强结论置信程度。 补充说明:本教程通过一个由正弦信号加白噪构造而成的简单实例来指导大家理解和执行QRBiLSTM流程的所有关键步骤,这既方便于初学者跟踪学习,又有利于专业人士作为现有系统的补充参考工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值