zoukankan      html  css  js  c++  java
  • 题解 CF145E Lucky Queries

    线段树。

    在树中我们维护四个东西:最长不下降子序列的长度,最长不上升子序列的长度,(4)的个数和(7)的个数。

    线段树最重要的是(push\,up),也就是合并。

    显然(4)的个数和(7)的个数就直接加一下,没什么好说的。

    因为数列中不是(4)就是(7),所以这个最长不下降子序列一定有一个(4)(7)的分界点。

    如果这个分界点在左儿子里,那么父节点的最长不下降子序列的长度就是左儿子的最长不下降子序列长度加上右儿子的(7)的个数。

    如果这个分界点在右儿子里,那么父节点的最长不下降子序列的长度就是左儿子的(4)的个数加上右儿子的最长不下降子序列长度。

    最长不上升子序列的长度同理。

    这部分的代码

    struct node
    {
    	ll l,r,mid,vals,valx,num4,num7;//vals是最长不上升子序列长度,valx是最长不下降子序列长度
    	bool tag;//lazy标记
    }seg[N<<2];
    inline void pushup(re ll pos)
    {
    	seg[pos].vals=max(seg[pos<<1].vals+seg[pos<<1|1].num7,seg[pos<<1].num4+seg[pos<<1|1].vals);
    	seg[pos].valx=max(seg[pos<<1].valx+seg[pos<<1|1].num4,seg[pos<<1].num7+seg[pos<<1|1].valx);
    	seg[pos].num4=seg[pos<<1].num4+seg[pos<<1|1].num4;
    	seg[pos].num7=seg[pos<<1].num7+seg[pos<<1|1].num7;
    	return;
    }
    

    建树就没什么可说的了,和正常的线段树建树一样,最长不上升子序列长度和最长不下降子序列的长度都赋为(1)

    inline void build(re ll pos,re ll l,re ll r)
    {
    	seg[pos].l=l;
    	seg[pos].r=r;
    	seg[pos].mid=l+r>>1;
    	if(l==r)
    	{
    		seg[pos].vals=seg[pos].valx=1;
    		seg[pos].num4=(a[l]==4);
    		seg[pos].num7=(a[l]==7);
    	}
    	else
    	{
    		build(pos<<1,l,seg[pos].mid);
    		build(pos<<1|1,seg[pos].mid+1,r);
    		pushup(pos);	
    	}
    	return;
    }
    

    修改操作就直接把最长不上升子序列的长度和最长不下降子序列的长度交换,(4)的数量和(7)的数量交换。

    标记下传

    inline void add(re ll pos)
    {
    	seg[pos].tag^=1;
    	swap(seg[pos].num4,seg[pos].num7);
    	swap(seg[pos].valx,seg[pos].vals);
    	return;
    }
    inline void pushdown(re ll pos)
    {
    	if(!seg[pos].tag)
    		return;
    	add(pos<<1);
    	add(pos<<1|1);
    	seg[pos].tag^=1;
    	return;
    }
    

    区间修改

    inline void upgrade(re ll pos,re ll l,re ll r)
    {
    	if(seg[pos].l>=l&&seg[pos].r<=r)
    		return add(pos);
    	else if(seg[pos].l>r||seg[pos].r<l)
    		return;
    	pushdown(pos);
    	upgrade(pos<<1,l,r);
    	upgrade(pos<<1|1,l,r);
    	pushup(pos);
    	return;
    }
    

    每次询问的结果就是seg[1].vals

    注意这个毒瘤的没有空格的输入就好了。

  • 相关阅读:
    Encryption (hard) CodeForces
    cf 1163D Mysterious Code (字符串, dp)
    AC日记——大整数的因子 openjudge 1.6 13
    AC日记——计算2的N次方 openjudge 1.6 12
    Ac日记——大整数减法 openjudge 1.6 11
    AC日记——大整数加法 openjudge 1.6 10
    AC日记——组合数问题 落谷 P2822 noip2016day2T1
    AC日记——向量点积计算 openjudge 1.6 09
    AC日记——石头剪刀布 openjudge 1.6 08
    AC日记——有趣的跳跃 openjudge 1.6 07
  • 原文地址:https://www.cnblogs.com/CelticBlog/p/13531726.html
Copyright © 2011-2022 走看看