HDU 5200 脑洞题 离线

线段树,TLE,各种。唉。。。。我真是笨死了。。。。

我用的线段树是记录左右区间最长连续棵数的。。。反正TLE

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int N=50050;
struct Q{
	int val,index;
}Que[N];
int SegT[N*4],L[N*4],R[N*4],C[N*4];
int TreeH[N];
int ans[N];
bool cmp(Q a,Q b){
	if(a.val<b.val) return true;
	return false;
}

void build(int l,int r,int rt){
	L[rt]=R[rt]=r-l+1;C[rt]=1;
	if(l==r){
		SegT[rt]=TreeH[l];
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,rt<<1);
	build(m+1,r,rt<<1|1);
	SegT[rt]=max(SegT[rt<<1],SegT[rt<<1|1]);
}

void slove(int l,int r,int rt,int hv){
	if(l==r){
		return ;
	}
	int m=(l+r)>>1;
	if(hv>=SegT[rt<<1])
	L[rt<<1]=R[rt<<1]=C[rt<<1]=0;
	else
	slove(l,m,rt<<1,hv);
	if(hv>=SegT[rt<<1|1]) L[rt<<1|1]=R[rt<<1|1]=C[rt<<1|1]=0;
	else
	slove(m+1,r,rt<<1|1,hv);
	L[rt]=L[rt<<1],R[rt]=R[rt<<1|1];
	if(L[rt<<1]>=m-l+1) L[rt]+=L[rt<<1|1];
	if(R[rt<<1|1]>=r-m) R[rt]+=R[rt<<1];
	C[rt]=C[rt<<1]+C[rt<<1|1];
	if(R[rt<<1]&&L[rt<<1|1]&&C[rt]) C[rt]--;
}

void readint1(int i) {  
    TreeH[i]=0;  
    char ch;  
    ch=getchar();  
    while(!isdigit(ch))ch=getchar();  
    while(isdigit(ch)){  
        TreeH[i]=TreeH[i]*10+ch-'0';  
        ch=getchar();  
    }    
}

int readint2(){  
    int x=0;  
    char ch;  
    ch=getchar();  
    while(!isdigit(ch))ch=getchar();  
    while(isdigit(ch)){  
        x=x*10+ch-'0';  
        ch=getchar();  
    }  
    return x;  
}

int main(){
	int n,q;
	while(scanf("%d%d",&n,&q)!=EOF){
		memset(ans,0,sizeof(int)*n);
		for(int i=1;i<=n;i++)
		readint1(i);
		build(1,n,1);
		for(int i=0;i<q;i++){
			Que[i].val=readint2();
			Que[i].index=i;
		}
		sort(Que,Que+q,cmp);
		for(int i=0;i<q;i++){
			if(Que[i].val>=SegT[1]){
				ans[Que[i].index]=0;
			}
			else{
				slove(1,n,1,Que[i].val);
				ans[Que[i].index]=C[1];
			}
		}
		for(int i =0;i<q;i++)
		printf("%d\n",ans[i]);
	}
	return 0;
}

  

这个是看了别人之后的解法,漂亮啊。。。

把树排序,把询问排序,都按高度。两个指针扫描,对于不高于询问高度的树,对其原本的位置,若左右均未砍去,则段数+1,若均砍去,则段数-1,除此外,段数不变。

再感叹一下,漂亮啊。。。。T_T

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
const int N=50050;

struct TH{
	int height,index;
}Tree[N],Que[N];
bool vis[N];
int n,q,ans[N];
bool cmp(TH a,TH b){
	if(a.height<b.height) return true;
	return false;
}

void work(int &c,int index){
	if(index==0){
		if(vis[index+1]) c--;
	}
	else if(index==n-1){
		if(vis[index-1]) c--;
	}
	else{
		if(!vis[index+1]&&!vis[index-1]) c++;
		else if(vis[index+1]&&vis[index-1]){
			c--;
		}
	}
}

int main(){
	while(scanf("%d%d",&n,&q)!=EOF){
		for(int i=0;i<n;i++){
			scanf("%d",&Tree[i].height);
			Tree[i].index=i;
		}
		sort(Tree,Tree+n,cmp);
		for(int i=0;i<q;i++){
			scanf("%d",&Que[i].height);
			Que[i].index=i;
		}
		sort(Que,Que+q,cmp);
		memset(vis,false,sizeof(vis));
		int ct=0;
		int counts=1;
		for(int i=0;i<q;i++){
			for(;ct<n;ct++){
				if(Tree[ct].height>Que[i].height) break;
				vis[Tree[ct].index]=true;
				work(counts,Tree[ct].index);
			}
			ans[Que[i].index]=counts;
		}
		for(int i=0;i<q;i++)
		printf("%d\n",ans[i]);
	}
	return 0;
}

  

 

posted @ 2015-04-09 22:25  chenjunjie1994  阅读(146)  评论(0编辑  收藏  举报