ZOJ Problem Set - 2505 Sticks
Chieh
posted @ 2014年12月08日 16:54
in ZOJ
, 221 阅读
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1505
题目大意:就是有最多1024个魔法棒放在一排,按照时间顺序对第i个魔法棒改变状态,问最长的连续子序列且都是奇数次改变多长。
题目分析:网上说是暴力。。。我暴力了一发。。。过了。。。但是这题明显是线段树啊,虽然暴力出奇迹。
怎么个线段法??就是每个区间记录最大值和是否是连续的区间。。怎么定义??一个节点定义lval,rval,link,max,l,r 其中l,r不用说了,lval就是左边的长度,val同理,max最大值,link是否连续,如果连续,那么lva=rval;如果不连续当然也可能相等,但是不可能是区间的长度,这样我们就好搞了,每次更新子节点,则父节点判断是否连续,如果两个子节点都连续,则父节点lval=左节点的lva+右节点的rval,且max就是当前区间长~~~link当然是连接的啊~~不想等呢》》
那好办了,如果左节点是连得,那父节点lval=左节点lval+右节点lval,且rval=右节点rval,link当然为false了,max就是lmax+rmax
如果右节点是连得,同理哈。。。最后一种情况左右都不连。。。那父节点lval=左节点lval,父节点rval=右节点val,max还是lmax+rmax,link必然false,OK了,讨论完毕。。。AC啦
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=4097; struct he { int l,r,MAX; int lval,rval; int link; } JLJ[maxn*2]; void BuildTree(int l,int r,int now) { JLJ[now].l=l; JLJ[now].r=r; JLJ[now].link=0; JLJ[now].MAX=0; JLJ[now].lval=0; JLJ[now].rval=0; if(l==r)return; int mid=(l+r)/2; BuildTree(l,mid,now*2); BuildTree(mid+1,r,now*2+1); } void Update(int l,int now) { if(JLJ[now].l==l&&JLJ[now].r==l) { if(JLJ[now].MAX==0)JLJ[now].MAX=1; else JLJ[now].MAX=0; JLJ[now].lval=JLJ[now].rval=JLJ[now].MAX; if(JLJ[now].MAX==1) JLJ[now].link=1; else JLJ[now].link=0; return; } int mid=(JLJ[now].l+JLJ[now].r)/2; if(l<=mid) { Update(l,now*2); } else { Update(l,now*2+1); } int j1=JLJ[now*2].link; int j2=JLJ[now*2+1].link; if(j1&&j2) { JLJ[now].link=1; JLJ[now].lval=JLJ[now].rval= JLJ[now].MAX=JLJ[now*2].MAX+JLJ[now*2+1].MAX; } else if(j1) { JLJ[now].link=0; JLJ[now].lval=JLJ[now*2].MAX+JLJ[now*2+1].lval; JLJ[now].rval=JLJ[now*2+1].rval; JLJ[now].MAX=max(JLJ[now].lval,max(JLJ[now*2+1].MAX,JLJ[now*2].MAX)); } else if(j2) { JLJ[now].link=0; JLJ[now].lval=JLJ[now*2].lval; JLJ[now].rval=JLJ[now*2].rval+JLJ[now*2+1].MAX; JLJ[now].MAX=max(JLJ[now*2].MAX,max(JLJ[now].rval,JLJ[now*2+1].MAX)); } else { JLJ[now].link=0; JLJ[now].lval=JLJ[now*2].lval; JLJ[now].rval=JLJ[now*2+1].rval; JLJ[now].MAX=max(JLJ[now*2].MAX,max(JLJ[now*2+1].MAX,JLJ[now*2].rval+JLJ[now*2+1].lval)); } } int T,n; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); BuildTree(1,4096,1); int l; int MAX=0; for(int i=1; i<=n; i++) { scanf("%d",&l); Update(l,1); MAX=max(MAX,JLJ[1].MAX); } printf("%d\n",MAX); } //cout << "Hello world!" << endl; return 0; }