2017ICPC北京赛区网络赛 Minimum(数学+线段树)
2017-09-25 20:35
351 查看
描述
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 分析得出,一区间的乘积最小值,只有三种情况 1.最大值的平方(最大值为负数) 2.最小值的平方(最小值为正数) 3.最大值与最小值的乘积(最大值是正,最小值为负) 得到此结果后,只需改一下线段树的模板,将每段区间的最大最小值保存下来即可。
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> using namespace std; const long long Max=140000; int n; struct node { long long b,s; }Tree[Max<<2]; long long bb,ss; void build(int k,int l,int r)//建线段树,k表示子节点坐标 { if(l == r) { scanf("%lld",&Tree[k].b); Tree[k].s=Tree[k].b; } else { int mid = (l+r)/2; build(k*2,l,mid); build(k*2+1,mid+1,r); Tree[k].b=max(Tree[k*2].b, Tree[k*2+1].b); Tree[k].s=min(Tree[k*2].s, Tree[k*2+1].s); } } void query(int a,int b,int k,int l,int r)//a,b是当前查询区间,k是当前的根节点,l,r是要求查询区间 { if(a >= l && b <= r) { bb=max(bb,Tree[k].b); ss=min(ss,Tree[k].s); //return min(min(Tree[k].b*Tree[k].b,Tree[k].b*Tree[k].s),Tree[k].s*Tree[k].s); return; } else { //long long ans = Max*Max; int mid = (a+b)/2; if(l <= mid)query(a,mid,k*2,l,r); if(r > mid) query(mid+1,b,k*2+1,l,r); return; //return ans; } } void update(int l,int r,int k,int pos,long long v)//l,r是查询区间,k是当前根节点,pos是查询位置 { if(l == r) { Tree[k].b=v; Tree[k].s=v; } else{ int mid = (l+r)/2; if(pos <= mid) update(l,mid,k*2,pos,v); if(pos > mid) update(mid+1,r,k*2+1,pos,v); Tree[k].b=max(Tree[k*2].b, Tree[k*2+1].b); Tree[k].s=min(Tree[k*2].s, Tree[k*2+1].s); } } int main() { int T,l,r,pos; long long val; int k,c,order; scanf("%d",&T); for(int t=1;t<=T;t++) { scanf("%d",&k); n=pow(2.0,k); build(1,1,n); scanf("%d",&c); while(c--) { scanf("%d",&order); if(order==1) { scanf("%d%d",&l,&r); bb=-Max;ss=Max; long long tmpans; query(1,n,1,l+1,r+1); tmpans= min(min(bb*bb,bb*ss),ss*ss); printf("%lld\n",tmpans); } else if(order==2)//点更新 { scanf("%d%lld",&pos,&val); update(1,n,1,pos+1,val); } } } return 0; }
相关文章推荐
- ACM-ICPC北京赛区(2017)网络赛-题目9 : Minimum(线段树)
- hihocoder1586 Minimum 2017icpc北京赛区 线段树区间最值
- HihoCoder-1586 Minimum(线段树,区间最值,ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum-(线段树)
- hihocoder-1586---Minimum(2017-icpc-网络赛-北京赛区)(线段树)
- ACM-ICPC北京赛区网络赛2017-minimum(线段树)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 题目9 : Minimum(线段树)
- 【线段树】hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 I. Minimum
- hihoCoder 1586 Minimum 【线段树】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 I.Minimum(线段树_单点修改,查询区间最大最少值)
- 北京赛区(2017)网络赛 之 Minimum(线段树)
- hihoCoder 1586 Minimum 【线段树】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 I.Minimum(线段树区间极值+分类讨论)
- Minimum (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 题9)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛——Minimum(I题)
- 2017 icpc 北京赛区 I.Minimum(线段树)
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 Minimum
- 北京赛区(2017)网络赛-I-线段树
- 2017ICPC北京赛区网络赛 G Bounce(GCD,找规律)
- 2017ICPC北京赛区网络赛 E Territorial Dispute(计算几何)