hihocoder-1586---Minimum(2017-icpc-网络赛-北京赛区)(线段树)

时间限制: 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

题意:给一串数字,两种操作,1 x y,查询区间x~y中a[x]*a[y]的最小值,先可以等于y;2  x   y,把a[i]改成y;

思路:线段树维护区间最大最小值+单点更新;每次查询区间最小值ans1和最大值ans2;ans1>=0,答案为ans1*ans1;ans1<0时,ans2<0,答案为ans2*ans2,ans2>=0,答案为ans1*ans2;

AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#define maxn 150000
#define inf 0x7fffffff
using namespace std;
long long  n,arr[maxn];
struct node
{
    int l;
    int r;
    long long int mi;
    long long int mx;
}segtree[maxn*4];
int tab[20];
void init()
{
    tab[0]=1;
    for(int i=1;i<=18;i++)
        tab[i]=tab[i-1]*2;
}
void pushup(int root)
{
    segtree[root].mi=min(segtree[root<<1].mi,segtree[root<<1|1].mi);
    segtree[root].mx=max(segtree[root<<1].mx,segtree[root<<1|1].mx);
}
void build(int root,int l,int r)
{
    segtree[root].l=l;
    segtree[root].r=r;
    if(l==r)
    {
        segtree[root].mi=segtree[root].mx=arr[l];
        return;
    }
    int mid=(l+r)>>1;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
    pushup(root);
}
long long int query_mi(int root,int l,int r)
{
    int ll=segtree[root].l;
    int rr=segtree[root].r;
    if(l<=ll&&rr<=r)
        return segtree[root].mi;
    int mid=(ll+rr)>>1;
    long long int ans=inf;
    if(l<=mid)
        ans=min(ans,query_mi(root<<1,l,r));
    if(r>mid)
        ans=min(ans,query_mi(root<<1|1,l,r));
    return ans;
}
long long int query_mx(int root,int l,int r)
{
    int ll=segtree[root].l;
    int rr=segtree[root].r;
    if(l<=ll&&rr<=r)
        return segtree[root].mx;
    int mid=(ll+rr)>>1;
    long long int ans=-inf;
    if(l<=mid)
        ans=max(ans,query_mx(root<<1,l,r));
    if(r>mid)
        ans=max(ans,query_mx(root<<1|1,l,r));
    return ans;
}
void update(int root,int p,long long int val)
{
    int ll=segtree[root].l;
    int rr=segtree[root].r;
    if(ll==rr)
    {
        segtree[root].mi=segtree[root].mx=val;
        return;
    }
    int mid=(ll+rr)>>1;
    if(p<=mid)
        update(root<<1,p,val);
    else
        update(root<<1|1,p,val);
    pushup(root);
}
int main()
{
    int t;
    init();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        n=tab[n];
        for(int i=1;i<=n;i++)
            scanf("%lld",&arr[i]);
        build(1,1,n);
        int m;
        scanf("%d",&m);
        while(m--)
        {
            int op,x;
            long long y;
            scanf("%d%d%lld",&op,&x,&y);

            if(op==1)
            {
                x++;y++;
                long long  ans1=query_mi(1,x,y);
                long long  ans2=query_mx(1,x,y);
                //cout<<ans1<<' '<<ans2<<endl;
                if(ans1>=0)
                    printf("%lld\n",ans1*ans1);
                else
                {
                    if(ans2>=0)
                        printf("%lld\n",ans1*ans2);
                    else
                        printf("%lld\n",ans2*ans2);
                }
            }
            else
                x++,update(1,x,y);
        }
    }
    return 0;
}


发布了76 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37171272/article/details/78072889