poj3368

我的第一道线段树题目,虽然一次提交成功,但1188MS的时间有点让人无法接受

题目链接:http://poj.org/problem?id=3368

做题过程中,写错了一个参数,结果调试了一个多小时,汗。。。。。

不过看了discuss后,此题可用RMQ解,但我还不知道神马是RMQ

线段树解法:

此题我用了离散化,将相同连续的数列作为一个节点,查找时如果查找到叶子节点时,返回所查找的当前数列长度,其他地方和普通线段树无差别

代码如下:

#include <stdio.h>
#include <stdlib.h>

struct node{
int l;
int r;
}n1[100005];
struct xian{
int max;
int l;
int r;
int left;
int right;
}n2[200010];
int flag=0;
int xianduan(int no,int i,int j)
{
int temp;
if(i<j)
{
n2[no].l=n1[i].l;
n2[no].r=n1[j].r;
n2[no].left=i;
n2[no].right=j;
n2[no].max=xianduan(no*2,i,(j+i)/2);
temp=xianduan(no*2+1,(j+i)/2+1,j);
if(temp>n2[no].max)
{
n2[no].max=temp;
}

return n2[no].max;
}
else
{
n2[no].l=n1[i].l;
n2[no].r=n1[i].r;
n2[no].max=n1[i].r-n1[i].l+1;
n2[no].left=i;
n2[no].right=j;
return n2[no].max;
}
}
int search(int no,int i,int j)
{
int temp1;
int temp2;
if(n2[no].left==n2[no].right)
{
return (j-i+1);
}
if(n2[no].l==i&&n2[no].r==j)
{
return n2[no].max;
}
else if(n2[2*no].r>=j)
{

return search(no*2,i,j);

}
else if(n2[2*no+1].l<=i)
{

return search(no*2+1,i,j);

}
else if(n2[2*no].r>=i&&n2[2*no+1].l<=j)
{

temp1= search(no*2,i,n2[no*2].r);
temp2= search(no*2+1,n2[no*2+1].l,j);
if(temp1>temp2)
return temp1;
else
return temp2;
}
}
int main(int argc, char** argv) {
int n,q,i,j,sa,tem,sta,k,left,right;
while(scanf("%d",&n)&&n)
{

k=1;
scanf("%d",&q);
for(i=1;i<=n;i++)
{
scanf("%d",&tem);
if(i==1)
{
sa=tem;
sta=1;
}
else
{

if(sa!=tem)
{
sa=tem;
n1[k].l=sta;
n1[k].r=i-1;
sta=i;
k++;
}
}

}
n1[k].l=sta;
n1[k].r=i-1;
xianduan(1,1,k);
for(j=1;j<=q;++j)
{
scanf("%d %d",&left,&right);
printf("%d\n",search(1,left,right));
}

}

return (EXIT_SUCCESS);
}



posted @ 2011-11-06 16:24  枫月寒  阅读(183)  评论(0编辑  收藏  举报