hdu5200 n棵树m次询问,每次询问独立砍掉小于b[i]的树,输出每次砍过的连通区域个数:技巧/离线
将询问的高度和树的高度都变成离线排个序,然后就可以把砍树变成加树
对于一个询问高度b[i],将还未加入的所有大于这个高度的树都加入,加入的树
1.左右相邻都有树?连通区域-1
2.左右相邻都没树?连通区域+1
再把这个位置种上树,最后输出答案==
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 struct dian{ 6 int h,id; 7 }a[50005],b[50005]; 8 int cmp(dian n1,dian n2) 9 { 10 return n1.h>n2.h; 11 } 12 int tmp[50005],ans[50005]; 13 int main() 14 { 15 int n,m,i,la,x; 16 while (~scanf("%d%d",&n,&m)) 17 { 18 for (i=1;i<=n;i++){ 19 scanf("%d",&a[i].h); 20 a[i].id=i; 21 } 22 for (i=1;i<=m;i++){ 23 scanf("%d",&b[i].h); 24 b[i].id=i; 25 } 26 sort(a+1,a+n+1,cmp); 27 sort(b+1,b+m+1,cmp); 28 memset(ans,0,sizeof(ans)); 29 memset(tmp,0,sizeof(tmp)); 30 la=1; x=0; 31 for (i=1;i<=m;i++){ 32 while (la<=n&&a[la].h>b[i].h){ 33 if (tmp[a[la].id-1]==1&&tmp[a[la].id+1]==1) x--; 34 if (tmp[a[la].id-1]==0&&tmp[a[la].id+1]==0) x++; 35 tmp[a[la].id]=1; la++; 36 } 37 ans[b[i].id]=x; 38 } 39 for (i=1;i<=m;i++) printf("%d\n",ans[i]); 40 } 41 return 0; 42 }