1. 程式人生 > >2017 ACM-ICPC 北京網絡賽 Minimum 線段樹

2017 ACM-ICPC 北京網絡賽 Minimum 線段樹

fin ase clu str case return long long then 線段樹單點更新

描述

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 }

2017 ACM-ICPC 北京網絡賽 Minimum 線段樹