题意:
输入一行数字,查询第i个数到第j个数之间的最大值。可以修改其中的某个数的值。
输入:
包含多组输入数据。
每组输入首行两个整数n,m。表示共有n个数,m次操作。
接下来一行包含n个整数。
接下来m行,每行包含一个字母s,两个整数a,b。
当s为’Q’,表示查询第a个数到第b个数之间的最大值。
当s为’U’,表示将第a个数更改为b。
输出:
每次查询输出一个结果,每次输出占一行。
题解:
点修改区间求最值,可以用树状数组模板。
具体见代码——
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int N = 200010; 8 9 int a[N], c[N]; 10 int t, n, m; 11 12 int lowbit(int x) 13 { 14 return x&(-x); 15 } 16 17 void Maxn(int x, int y) 18 { 19 a[x] = y; 20 for(int i = x; i <= n; i += lowbit(i)) //需要修改的c[] 21 { 22 c[i] = y; 23 for(int j = 1; j < lowbit(i); j <<= 1) //修改时需要比较的c[] 24 { 25 c[i] = c[i] > c[i-j] ? c[i] : c[i-j]; 26 } 27 } 28 } 29 30 void Init() 31 { 32 int y; 33 memset(c, 0, sizeof(c)); 34 for(int i = 1; i <= n; i++) 35 { 36 scanf("%d", &y); 37 a[i] = y; 38 c[i] = y; 39 for(int j = 1; j <lowbit(i); j <<= 1) //需要比较的c[] 40 c[i] = c[i] > c[i-j] ? c[i] : c[i-j]; 41 } 42 } 43 44 void Query(int l, int r) 45 { 46 int ans = 0; 47 while(1) 48 { 49 ans = ans > a[r] ? ans : a[r]; 50 if(r == l) break; 51 for(r -= 1; r-l >= lowbit(r); r -= lowbit(r)) 52 ans = ans > c[r] ? ans : c[r]; 53 } 54 printf("%d\n", ans); 55 } 56 57 void Work() 58 { 59 char s[2]; 60 int x, y; 61 for(int i = 1; i <= m; i++) 62 { 63 scanf("%s%d%d", s, &x, &y); 64 if(s[0] == ‘U‘) Maxn(x, y); 65 else if(s[0] == ‘Q‘) Query(x, y); 66 } 67 } 68 69 int main() 70 { 71 //freopen("test.in", "r", stdin); 72 while(~scanf("%d%d", &n, &m)) 73 { 74 Init(); 75 Work(); 76 } 77 }
树状数组区间求最值模板——
http://www.cnblogs.com/mypride/p/5002556.html
时间: 2024-10-11 17:10:02