您的位置:首页 > 理论基础 > 计算机网络

hihocoder 1586 : Minimum ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛

2017-10-10 19:21 441 查看
时间限制:1000ms
单点时限:1000ms
内存限制:256MB


描述

You are given a list of integers a0, a1,
…, a2^k-1.
You need to support two types of queries:
1. Output Minx,y∈[l,r] {ax∙ay}.
2. Let ax=y.


输入

The first line is an integer T, indicating the number of test cases. (1≤T≤10).
For each test case:
The first line contains an integer k (0 ≤ k ≤ 17).
The following line contains 2k integers, a0,
a1, …, a2^k-1 (-2k ≤
ai < 2k).
The next line contains a integer  (1 ≤ Q < 2k), indicating the number of queries. Then next Q lines, each
line is one of:
1. 1 l r: Output Minx,y∈[l,r]{ax∙ay}.
(0 ≤ l ≤ r < 2k)
2. 2 x y: Let ax=y. (0 ≤ x < 2k,
-2k ≤ y < 2k)


输出

For each query 1, output a line contains an integer, indicating the answer.

样例输入
1
3
1 1 2 2 1 1 2 2
5
1 0 7
1 1 2
2 1 2
2 2 2
1 1 2


样例输出
1
1
4


刚刚写出了人生第一个线段树求区间最大最小值代码

之前遇到的都是用树状数组做,树状数组能力太小。很多情况不能处理

当然代码是根据模板修修改改写的,写下来的感觉就是几个函数体里面的内容大差不差

硬背模板的情况下还是感觉很容易的

另外附一个大牛博客:http://blog.csdn.net/metalseed/article/details/8039326

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int INF=1<<29;
int max_tree[300000];
int min_tree[300000];
int a[300000];
void build(int node,int begin,int end){
if(begin==end) min_tree[node]=a[begin],max_tree[node]=a[begin];
else{
build(2*node,begin,(begin+end)/2);

build(2*node+1,(begin+end)/2+1,end);

max_tree[node]=max(max_tree[2*node],max_tree[2*node+1]);

min_tree[node]=min(min_tree[2*node],min_tree[2*node+1]);
}
}
int findmin(int node,int begin,int end,int z,int y){
int p1=INF,p2=INF;
if(begin>=z&&end<=y) return min_tree[node];
int fz=(begin + end) / 2;
if(z<=fz)
p1=findmin(2*node,begin,fz, z, y) ;
if(y>fz)
p2=findmin(2*node+1,fz+1,end,z,y);
return min(p1,p2);
}
int findmax(int node,int begin,int end,int z,int y){
int p1=-INF,p2=-INF;
if(begin>=z&&end<=y) return max_tree[node];
int fz=(begin + end) / 2;
if(z<=fz)
p1=findmax(2*node,begin,fz, z, y) ;
if(y>fz)
p2=findmax(2*node+1,fz+1,end,z,y);
return max(p1,p2);
}
void updata(int node,int begin,int end,int x,int num){
if(begin==end){
min_tree[node]=num;
max_tree[node]=num;
return;
}
int fz=(begin+end)/2;
if(x<=fz) updata(node*2,begin,fz,x,num);
else updata(node*2+1,fz+1,end,x,num);
min_tree[node]=min(min_tree[2*node],min_tree[2*node+1]);
max_tree[node]=max(max_tree[2*node],max_tree[2*node+1]);
}
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
n=pow(2,n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
int m;
cin>>m;
for(int i=0;i<m;i++){
int index,x,y;
cin>>index>>x>>y;
x++;
if(index==1){
y++;
long long minn=findmin(1,1,n,x,y);

long long maxn=findmax(1,1,n,x,y);
if(maxn<=0) printf("%lld\n",maxn*maxn);
else if(minn>=0) printf("%lld\n",minn*minn);
else printf("%lld\n",minn*maxn);
}
else{
updata(1,1,n,x,y);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐