hihoCoder

来源:互联网 发布:如何注册淘宝联盟账号 编辑:程序博客网 时间:2024/06/05 18:48

题目链接
思路:操作1:单点更新 操作2。找到区间 的最值无非三种情况。
坑点:下标重0开始的

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cctype>#include <sstream>#include <cmath>using namespace std;const int inf =0x3f3f3f3f;typedef long long LL;const int MAXN = 200005;struct Tree{    int Max, Min;    int l, r ;} tree[MAXN*4];int a[MAXN];int n;void pushup(int k){    tree[k].Max =max(tree[k<<1].Max,tree[k<<1|1].Max);    tree[k].Min =min(tree[k<<1].Min,tree[k<<1|1].Min);}void build(int k, int l, int r)//建树的模板操作,通过递归和二分{    tree[k].l  = l;    tree[k].r  = r;    if(l==r)    {        tree[k].Max=tree[k].Min=a[l];        return ;    }    int mid;    mid = (tree[k].l+tree[k].r)>>1;    build(k<<1, l, mid);    build(k<<1|1,mid+1,r);    pushup(k);    return ;}void update(int k, int pos, int c){    if(pos ==  tree[k].l && tree[k].r == pos)    {        tree[k].Max=tree[k].Min=c;        return ;    }    int mid=(tree[k].l+tree[k].r)>>1;    if(pos<=mid)        update(k<<1, pos, c);    else        update(k<<1|1, pos,c);    pushup(k);}LL Search1(int l, int r, int k)//query{    int mid;    LL Max=-inf;    if(tree[k].l>=l&&tree[k].r<=r)        return Max = tree[k].Max;    mid = (tree[k].l+tree[k].r)>>1;    if(l<=mid)        Max=max(Max, Search1(l, r, k<<1));    if(r>mid)        Max=max(Max,Search1(l, r, k<<1|1));    return Max;}LL Search2(int l, int r, int k)//query{    int mid;    LL Min=inf;    if(tree[k].l>=l&&tree[k].r<=r)        return tree[k].Min;    mid = (tree[k].l+tree[k].r)>>1;    if(l<=mid)        Min = min(Min, Search2(l, r, k<<1));    if(r>mid)        Min = min(Min, Search2(l, r, k<<1|1));    return Min;}int main(){    int t, k;    scanf("%d", &t);    while(t--)    {        scanf("%d", &k);        n=1<<k;        for(int i=1;i<=n;++i)            scanf("%d", &a[i]);        build(1, 1, n);        //for(int i=1;i<=15;++i)        //printf("%d %lld %lld %lld %lld\n", i, tree[i].l, tree[i].r, tree[i].Max, tree[i].Min);        int q;        scanf("%d",&q);        while(q--)        {            int op ;            int x, y;            scanf("%d %d %d", &op, &x, &y);            x++;            if(op==2)                update(1, x, y);            else            {                LL Max, Min;                y++;                Max=Search1(x, y, 1);                Min=Search2(x, y, 1);                LL ans;                ans=min(Max*Max, Min*Min);                ans=min(Min*Max, ans);                //printf("%lld %lld\n", Max, Min);                printf("%lld\n", ans);            }        }    }    return 0;}