hdoj1540 【线段树的表示】
大牛blog
这题的题解写给自己看……
总结(瞎扯一点):
之前只会思考,len,sum,然后GG,如果只是sum和len的去用的话,就是在mid的时候会GG。然后这次也是参考大牛的写法,其实还是蛮简单的,写完以后觉得。。。直接搞两个左边连续,右边连续,然后区间最大,直接弄弄就好了,但是具体实现,如果没有很多的练习,绝对是错误百出啊!
先讲小东西:
①:建树,以后再根据自己的瞎瘠薄在挑战上看了文字自己写的建树真是丑爆了,以后还是用好看的写法写,,,,
小东西没有了。
大东西:
①:update,卧槽,看完大牛blog后面自己写,直接蒙比了///完全就是乱写带节奏。。。其实很简单:一、找一个能return的条件,return掉;二、如果不能,下来的步骤就是继续(搜索)下去,本来就是个递归嘛。三、搜索完以后,你回来的那个节点还没有处理过,也就是那个节点的我所需要的信息还没有处理过。那么就要考虑各种情况,把这个节点处理的干干净净,处理的非常奈斯。
二、query,主要还是线段树的节点信息处理的好的话,query就非常方便,这也不讲了。
PS:这题恶心到的是,特么还是多组数据,先是打完代码,找了半小时错误,然后莫名其妙再wa了5,6发,哎,心累。。。讲道理,这道题目有说多组数据么?
再说一下,线段树对于练习的话,在DEV编译器练习比较不错,什么提示都没有,完全看自己思路。
OK,GG,贴份挫code跑。。。
挫code……………
#include<cstdio>
#include<math.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e4+10;
struct asd{
int left,right;
int ls,rs;
int ms;
};
asd q[N*20];
void build(int num,int L,int R)
{
q[num].left=L;
q[num].right=R;
q[num].ls=q[num].rs=q[num].ms=R-L+1;
if(L!=R)
{
int mid=(L+R)/2;
build(2*num,L,mid);
build(2*num+1,mid+1,R);
}
}
int query(int num,int t)
{
if(q[num].left==q[num].right||q[num].ms==0||q[num].ms==(q[num].right-q[num].left+1))
return q[num].ms;
int mid=(q[num].right+q[num].left)/2;
if(t<=mid)
{
if(t>=(q[2*num].right-q[2*num].rs+1))
return query(2*num,t)+query(2*num+1,mid+1);
else
return query(2*num,t);
}
else
{
if(t<=q[2*num+1].left+q[2*num+1].ls-1)
return query(2*num+1,t)+query(2*num,mid);
else
return query(2*num+1,t);
}
}
void update(int num,int t,int x)
{
if(q[num].left==q[num].right)
{
if(x==1)
q[num].ls=q[num].rs=q[num].ms=1;
else
q[num].ls=q[num].rs=q[num].ms=0;
return;
}
int mid=(q[num].left+q[num].right)/2;
if(mid>=t)
update(2*num,t,x);
else
update(2*num+1,t,x);
q[num].ls=q[2*num].ls;
q[num].rs=q[2*num+1].rs;
q[num].ms=max(q[2*num].ms,max(q[2*num+1].ms,q[2*num].rs+q[2*num+1].ls));
if(q[2*num].ls==(q[2*num].right-q[2*num].left+1))
q[num].ls+=q[2*num+1].ls;
if(q[2*num+1].rs==(q[2*num+1].right-q[2*num+1].left+1))
q[num].rs+=q[2*num].rs;
}
int re[N*5];
int main()
{
char ss[5];
int n,m,x,pos,u;
while(~scanf("%d%d",&n,&m))
{
scanf("%d%d",&n,&m);
build(1,1,n);
pos=0;
for(int i=0;i<m;i++)
{
scanf("%s",ss);
if(strcmp(ss,"R")==0)
{
u=re[pos];
pos--;
update(1,u,1);
}
else if(strcmp(ss,"D")==0)
{
scanf("%d",&x);
re[++pos]=x;
update(1,x,0);
}
else
{
scanf("%d",&x);
printf("%d\n",query(1,x));
}
}
}
return 0;
}