#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
int a[200005],belong[200005],L[200005],R[200005],ans[200005];
// 数据 所属的块 左界 右界 最大值数据
/* the first thing that I should do
1.将他们分组
2.区分左右值
3.算好他们的组中最大值
*/
int main()
{
int m,n;
while (scanf("%d %d",&n,&m)!=EOF){
int len = sqrt(n);
int teams = n/len;
if (n%len != 0)teams ++;
for (int i = 0;i < 200005;i ++)
ans[i] = 0;
for (int i = 1;i <= n;i ++){
scanf("%d",&a[i]);
belong[i] = i/len;
if (i%len != 0)belong[i] ++;
ans[belong[i]] = max(ans[belong[i]],a[i]);
}
// 划分左右界
int j = 1;
for(int i=1;i<=teams;i++){
L[i]=R[i-1]+1;
R[i]=min(L[i]+len-1,n);
}
// L[j] = 1;
// for (int i = 1;i <= n-1;i ++){
// if(belong[i]!=belong[i+1]){
// R[j++] = i;
// L[j] = i+1;
// }
// }
// R[j] = n;
while (m --){
char str[2];
int x,y;
int maxscore;
scanf("%s %d %d",str,&x,&y);
if (str[0] == 'U'){
a[x] = y;
ans[belong[x]]=0;
// 所在的组为belong[x]
for (int i = L[belong[x]];i <= R[belong[x]];i ++){
ans[belong[i]] = max(ans[belong[i]],a[i]);
}
}else {
maxscore=0;
if (belong[x] == belong[y]){
for (int i = x;i <= y;i ++){
maxscore = max(a[i],maxscore);
}
}
else {
for (int i = belong[x]+1;i <= belong[y]-1;i ++){
maxscore = max(ans[i],maxscore);
}
for (int i = x;i <= R[belong[x]];i ++){
maxscore = max(a[i],maxscore);
}
for (int i = L[belong[y]];i <= y;i ++)
maxscore = max(a[i],maxscore);
}
printf("%d\n",maxscore);
}
}
}
return 0;
}
分块优化
#include <iostream>
#include <cmath>
#include <algorithm>
#include <memory.h>
using namespace std;
int R[200005],L[200005],hi[200005],team[200005],maxTeam[200005];
int main()
{
int m,n;
while (cin >> m >> n){
for (int i = 1;i <= m;i ++)
cin >> hi[i];
//开始分组
int len = sqrt(m);
int teams = (m+len-1)/len;
for (int i = 1;i <= m;i ++)
team[i] = (i + len - 1)/len;
//确定左右值
for (int i = 1;i <= teams;i ++){
L[i] = 1+len*(i-1);
R[i] = min(L[i]+len-1,m);
}
memset (maxTeam,0,sizeof(maxTeam));
for (int i = 1;i <= teams;i ++){
for (int j = L[i];j <= R[i];j ++)
maxTeam[i] = max(maxTeam[i],hi[j]);
}
while (n --){
int maxNum = 0;
char str[2];
cin >> str;
int Locate,Rocate;
cin >> Locate >> Rocate;
if (str[0] == 'Q'){
if (team[Locate] != team[Rocate]){
for (int i = Locate;i <= R[team[Locate]];i ++)
maxNum = max(maxNum,hi[i]);
for (int i = team[Locate]+1;i <= team[Rocate]-1;i ++)
maxNum = max(maxTeam[i],maxNum);
for (int i = L[team[Rocate]];i <= Rocate;i ++)
maxNum = max(maxNum,hi[i]);
}else {
for (int i = Locate;i <= Rocate;i ++)
maxNum = max(maxNum,hi[i]);
}
cout << maxNum << endl;
} else {
hi[Locate] = Rocate;
maxTeam[team[Locate]] = 0;
for (int i = L[team[Locate]];i <= R[team[Locate]];i ++)
maxTeam[team[Locate]] = max(maxTeam[team[Locate]],hi[i]);
}
}
}
return 0;
}
分块里面最最容易错的就是那个L[team[Locate]]那里面是组数啊,组数。非常容易错的