分块水过。看了讨论版,发现我写的O(n * sqrt(m))的分块比O(n * m)的暴力还要慢
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5;
int A[MAXN],B,Max[MAXN];
int l[MAXN],r[MAXN];
int m,n,block,siz;
int main()
{
scanf("%d %d",&m,&n);
block = sqrt(m);
siz = m/block;
if(m%block) ++siz;
for(int i = 1; i <= siz; ++i)
{
l[i] = (i-1)*block+1;
r[i] = i*block;
}
r[siz] = m;
for(int i = 1; i <= m; ++i)
scanf("%d",&A[i]);
for(int i = 1; i <= siz; ++i)
for(int j = l[i]; j <= r[i]; ++j)
if(A[j] > Max[i])
Max[i] = A[j];
int bnum;
for(int i = 1; i <= n; ++i)
{
scanf("%d",&B);
if(B <= A[1]) continue;
for(int i = 1; i <= siz; ++i)
{
if(Max[i] >= B)
{
//这是前一块的事
if(A[l[i]] >= B)
{
bnum = i-1;
A[r[bnum]] += 1;
for(int j = l[bnum]; j <= r[bnum]; ++j)
Max[bnum] = max(Max[bnum],A[j]);
}
//这才属于当前块
else
{
for(int j = l[i]; j < r[i]; ++j)
{
if(A[j+1] >= B)
{
A[j] += 1;
break;
}
}
for(int j = l[i]; j <= r[i]; ++j)
Max[i] = max(Max[i],A[j]);
}
break;
}
}
}
for(int i = 1; i <= m; ++i)
printf("%d\n",A[i]);
return 0;
}