T 1 T_1 T1——block(3829)
Description:
有一排
n
n
n个积木,每个的高度为
h
i
h_i
hi,现在有水从
0
0
0开始每秒上涨
1
1
1单位,
求
m
m
m次询问,每次询问
s
s
s秒时,积木没被淹没的连通块个数。
n
,
m
≤
500000
,
h
i
≤
1
0
9
,
s
i
≤
s
j
(
i
≤
j
)
n,m\le 500000,h_i\le10^9,s_i\le s_j(i\le j)
n,m≤500000,hi≤109,si≤sj(i≤j)
Solution:
- 对于询问的时间是单调增的,那么我们就可以先将积木排序,
- 对于每次询问,看这次被淹没的积木中,每个的相邻积木是否也被淹没,
- 从而分类讨论计算贡献即可。
- 复杂度是线性的 Θ ( n ) \Theta(n) Θ(n)
Code:
#include<bits/stdc++.h>
using namespace std;
#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;++i)
template<class T>inline void Rd(T &x){
x=0;char c;
while((c=getchar())<48);
do x=(x<<1)+(x<<3)+(c^48);
while((c=getchar())>47);
}
const int N=5e5+2;
int n,m;
int A[N];
struct p60{
void solve(){
while(m--){
int s;Rd(s);
int ans=0;
for(int i=1;i<=n;++i){
int j=i;
while(A[j]>s && j<=n)++j;
if(j>i)ans++;
i=j;
}
printf("%d\n",ans);
}
}
}p1;
struct p100{
struct node{
int h,id;
bool operator<(const node &_)const{
return h<_.h;
}
}B[N];
bool mark[N];
void solve(){
REP(i,1,n) B[i]=(node){A[i],i},mark[i]=1;
sort(B+1,B+1+n);
int ans=1,now=1;
while(m--){
int s;Rd(s);
while(now<=n and B[now].h<=s){
int x=B[now].id;
if(mark[x-1] and mark[x+1]) ++ans;
if(!mark[x-1] and !mark[x+1]) --ans;
mark[x]=0;
now++;
}
printf("%d\n",ans);
}
}
}p2;
int main(){
// freopen("block.in","r",stdin);
// freopen("block.out","w",stdout);
Rd(n),Rd(m);
REP(i,1,n) Rd(A[i]);
if(n<=5000 && m<=5000)p1.solve();
else p2.solve();
return 0;
}
T 2 T_2 T2——dining
Description: