2017 ACM-ICPC 北京网络赛 Minimum 线段树

描述

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

一道线段树单点更新模版题,比赛的时候居然因为N定义小了WA,可是我明明放大了呀,摊手jpg。
  1 #include<iostream>
  2 #include<math.h>
  3 #include<algorithm>
  4 #define ll long long
  5 #define MAX_N 132000
  6 
  7 using namespace std;
  8 
  9 struct node
 10 {
 11     ll minn,maxx;
 12     int l,r;
 13 }num[MAX_N*4];
 14 int pp[MAX_N];
 15 void pushUp(int count)
 16 {
 17     num[count].minn = min(num[count<<1].minn,num[count<<1|1].minn);
 18     num[count].maxx = max(num[count<<1].maxx,num[count<<1|1].maxx);
 19 }
 20 void built_tree(int l,int r,int count)
 21 {
 22     num[count].l=l;
 23     num[count].r=r;
 24     if(l==r)
 25     {
 26         num[count].minn = pp[l];
 27         num[count].maxx = pp[l];
 28         return ;
 29     }
 30     int mid = (l+r)/2;
 31     built_tree(l, mid, count*2);
 32     built_tree(mid+1, r, count*2+1);
 33     pushUp(count);
 34 }
 35 ll query(int l,int r,int count,int flag)
 36 {
 37     if(num[count].l==l && num[count].r==r)
 38     {
 39         if(flag)
 40             return num[count].minn;
 41         else
 42             return num[count].maxx;
 43     }
 44     int mid = (num[count].l+num[count].r)/2;
 45     if(r<=mid)
 46         return query(l,r, count<<1,flag);
 47     else
 48         if(l>mid)
 49             return query(l, r, count<<1|1,flag);
 50         else
 51         {
 52             if(flag)
 53                 return  min(query(l, mid,count<<1,flag),query(mid+1, r, count<<1|1,flag));
 54             else
 55                 return  max(query(l, mid,count<<1,flag),query(mid+1, r, count<<1|1,flag));
 56         }
 57 }
 58 void update(int count,int pos,int val)
 59 {
 60     if(num[count].l==num[count].r)
 61     {
 62         num[count].minn=val;
 63         num[count].maxx=val;
 64         return ;
 65     }
 66     int mid = (num[count].l+num[count].r )/2;
 67     if(pos <= mid)
 68     {
 69         update(count<<1,pos,val);
 70     }
 71     else
 72         update(count<<1|1,pos,val);
 73     
 74     pushUp(count);
 75 }
 76 int main()
 77 {
 78     cin.sync_with_stdio(false);
 79     int t,n;
 80     cin>>t;
 81     while(t--)
 82     {
 83         cin>>n;
 84         n = pow(2,n);
 85         for(int i = 1; i <= n; i++)
 86             cin>>pp[i];
 87         
 88         built_tree(1, n, 1);
 89         
 90         int q,flag,l,r;
 91         cin>>q;
 92         for(int i = 1; i <= q; i++)
 93         {
 94             cin>>flag>>l>>r;
 95             if(flag==1)
 96             {
 97                 ll minn = query(l+1,r+1,1,1);
 98                 ll maxx = query(l+1,r+1,1,0);
 99                 if(maxx<0)
100                     cout<<maxx*maxx<<endl;
101                 else
102                 {
103                     if(minn<0)
104                         cout<<minn*maxx<<endl;
105                     else
106                         cout<<minn*minn<<endl;
107                 }
108             }
109             else
110             {
111                 update(1,l+1,r);
112             }
113         }
114     }
115     return 0;
116 }
原文地址:https://www.cnblogs.com/Xycdada/p/7586054.html