题目9 : Minimum
-
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
样例输出
描述
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 14
题目的意思是:1的话输出 x--y区间最小的乘积 2是让a[x]=y;算是修改点
直接求区间最大最小值和修改单点
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=150005;
const int maxx=0x3f3f3f3f;
long long h[maxn],a[maxn],b[maxn];
long long n,m;
long long pow1(long long a,long long b)
{
long long ans=1;
long long aa=a;
while(b)
{
if(b&1)
ans=ans*aa;
aa=aa*aa;
b=b/2;
}
return ans;
}
long long lowbit(long long x)
{
return x & (-x);
}
void updatemax(long long x)//a 是max
{
long long i,temp;
while(x<=n)
{
a[x]=h[x];
temp=lowbit(x);
for(i=1;i<temp;i<<=1)
a[x]=max(a[x],a[x-i]);
x+=lowbit(x);
}
}
void updatemin(long long x)//b 存小的
{
long long i,temp;
while(x<=n)
{
b[x]=h[x];
temp=lowbit(x);
for(i=1;i<temp;i<<=1)
b[x]=min(b[x],b[x-i]);
x+=lowbit(x);
}
}
long long findansmax(long long begin,long long end)
{
long long ans=-maxx;
while(end>=begin)
{
ans=max(ans,h[end]);
end--;
for(;end-lowbit(end)>=begin;end-=lowbit(end))
ans=max(ans,a[end]);
}
return ans;
}
long long findansmin(long long begin,long long end)
{
long long ans=maxx;
while(end>=begin)
{
ans=min(ans,h[end]);
end--;
for(;end-lowbit(end)>=begin;end-=lowbit(end))
ans=min(ans,b[end]);
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld",&n);
n=pow1(2,n);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(long long i=1;i<=n;i++)
{
scanf("%lld",&h[i]);
updatemin(i);
updatemax(i);
}
scanf("%lld",&m);
int q;
long long x,y;
for(long long i=1;i<=m;i++)
{
scanf("%d%lld%lld",&q,&x,&y);
if(q==2)//update
{
h[x+1]=y;
updatemin(x+1);
updatemax(x+1);
}
else
{
long long ans_1=findansmin(x+1,y+1);
long long ans_2=findansmax(x+1,y+1);
if(ans_1>=0)//同时大于等于0
printf("%lld\n",ans_1*ans_1);
else//ans_1 <0
{
if(ans_2<=0)
printf("%lld\n",ans_2*ans_2);
else
printf("%lld\n",ans_1*ans_2);
}
}
}
}
return 0;
}
其实也就是几个板子套一块~好好理解每一个函数是干嘛用的~