BestCoder Round #36(Trees-離線處理詢問),
TreesAccepts: 156Submissions: 533Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)問題描述
今天CodeFamer去坎樹。有N 棵樹排成一排。他們被從1 到N 標號。第i 號樹的高度為h i 。兩棵未被坎掉的樹編號分別為x,y
若且唯若他們滿足如下條件中一條時,他們是屬於同一個塊的:1) x+1=y 或 y+1=x;2) 存在一個棵未被坎掉的樹,編號為z ,x 和z 在同一個塊並且y 和z 也在同一個塊。現在CodeFamer想要坎掉一些高度不大於某個值的樹,坎掉之後會形成多少個塊呢?
輸入描述
多組測試資料(大概15 組)對於每一組資料,第一行包含兩個整數N 和Q ,以一個空格分開,N 表示有N 棵樹,Q 表示有Q 個查詢。在接下來的N 行中,會出現h[1],h[2],h[3],…,h[N] ,表示N 棵樹的高度。在接下來的Q 行中,會出現q[1],q[2],q[3],…,q[Q] 表示CodeFamerr查詢。請處理到檔案末尾。[參數約定]1≤N,Q≤50000 0≤h[i]≤1000000000(10 9 ) 0≤q[i]≤1000000000(10 9 )
輸出描述
對於每一個q[i],輸出CodeFamer坎掉高度不大於q[i]的樹之後有多少個塊。
輸入範例
3 252362
輸出範例
02
Hint
在這個範例中,有3棵樹,他們的高度依次是5 2 3。對於6這個查詢,如果CodeFamer坎掉高度不大於6的樹,那麼剩下的樹高度形狀是-1 -1 -1(-1表示那個樹被坎掉了)。這樣就有0個塊。對於2這個查詢,如果CodeFamer坎掉高度不大於2的樹,那麼剩下的樹高度形狀是5 -1 3(-1表示那個樹被坎掉了)。這樣就有2個塊。
Statistic |Submit | Clarifications | Back
離線處理詢問
#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<functional>#include<iostream>#include<cmath>#include<cctype>#include<ctime>#include<vector>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (x<<1)#define Rson ((x<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define MAXN (50000+10)#define fi first#define se second typedef long long ll;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int n,Q;ll h[MAXN],q[MAXN];bool b[MAXN];pair<ll,int> ask[MAXN],work[MAXN];int sum[MAXN];int main(){//freopen("c.in","r",stdin);while(scanf("%d%d",&n,&Q)==2){MEM(h) MEM(q) MEM(b)For(i,n){scanf("%d",&h[i]);work[i]=make_pair(h[i],i); b[i]=1;}sort(work+1,work+1+n);For(i,Q){scanf("%d",&q[i]);ask[i]=make_pair(q[i],i); } sort(ask+1,ask+1+Q);int i=1,j=1,ans=1;while (j<=Q){if (i<=n&&work[i].fi<=ask[j].fi) //cut tree{int now=work[i].se;b[now]=0;ans+=b[now-1]+b[now+1]-1;i++;}else // calc ans{int now=ask[j].se;sum[now]=ans;j++;}} For(i,Q) printf("%d\n",sum[i]);}return 0;}