noip 2018 模擬賽10
阿新 • • 發佈:2018-12-18
——block(3829)
Description:
有一排個積木,每個的高度為,現在有水從開始每秒上漲單位, 求次詢問,每次詢問秒時,積木沒被淹沒的連通塊個數。
Solution:
- 對於詢問的時間是單調增的,那麼我們就可以先將積木排序,
- 對於每次詢問,看這次被淹沒的積木中,每個的相鄰積木是否也被淹沒,
- 從而分類討論計算貢獻即可。
- 複雜度是線性的
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; }
——dining
Description: