zoukankan      html  css  js  c++  java
  • 题解 P3870 【[TJOI2009]开关】

    这个题我愣是交了好几遍没有过......
    后来@_皎月半洒花dalao告诉我说要^儿子节点的tag,然后就明白了......

    行吧,先上题面:

    题目描述

    现有N(2 ≤ N ≤ 100000)盏灯排成一排,从左到右依次编号为:1,2,......,N。然后依次执行M(1 ≤ M ≤ 100000)项操作,操作分为两种:第一种操作指定一个区间[a, b],然后改变编号在这个区间内的灯的状态(把开着的灯关上,关着的灯打开),第二种操作是指定一个区间[a, b],要求你输出这个区间内有多少盏灯是打开的。灯在初始时都是关着的。

    输入输出格式

    输入格式:

    第一行有两个整数N和M,分别表示灯的数目和操作的数目。接下来有M行,每行有三个整数,依次为:c, a, b。其中c表示操作的种类,当c的值为0时,表示是第一种操作。当c的值为1时表示是第二种操作。a和b则分别表示了操作区间的左右边界(1 ≤ a ≤ b ≤ N)。

    输出格式:

    每当遇到第二种操作时,输出一行,包含一个整数:此时在查询的区间中打开的灯的数目。

    这个题比较有好处的一点是有很多题都和这个题基本一样。
    然后我们看到这个题让我们统计一个线段内的某一种和和修改区间:

    线段树啊!

    然后我就把校门外的树的代码扒过来了......
    评测记录
    后果:听取WA声一片。

    为啥呢?

    因为儿子节点有可能比父亲节点提前改过了。
    所以我们只能取反,把原先的状态反过来。
    然后就成了提交记录

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    const int maxn=100001;
    struct tree{
    	int l,r,flash,dark;
    	bool tag;
    }segment[maxn<<2];
    int n,m;
    
    inline void update(int rt);
    inline void pushdown(int rt);
    inline void build_tree(int rt,int l,int r);
    inline int query(int rt,int l,int r);
    inline void modify(int rt,int l,int r);
    
    int main()
    {
    	cin>>n>>m;
    	build_tree(1,1,n);
    	while (m--)
    	{
    		char flag;
    		int l,r;
    		cin>>flag>>l>>r;
    		if (flag=='0')modify(1,l,r);
    		else cout<<query(1,l,r)<<'
    ';
    	}
    	return 0;
    }
    
    inline void update(int rt)
    {
    	int lson=rt<<1,rson=lson+1;
    	segment[rt].flash=segment[lson].flash+segment[rson].flash;
    	segment[rt].dark=segment[lson].dark+segment[rson].dark;
    }
    inline void pushdown(int rt)
    {
    	int lson=rt<<1,rson=lson+1;
    	segment[lson].tag^=1;
    	segment[rson].tag^=1;
    	swap(segment[lson].dark,segment[lson].flash);
    	swap(segment[rson].dark,segment[rson].flash);
    	segment[rt].tag^=1;
    }
    inline void build_tree(int rt,int l,int r)
    {
    	segment[rt].l=l,segment[rt].r=r;
    	if (l==r)
    	{
    		segment[rt].flash=0;
    		segment[rt].dark=1;
    		segment[rt].tag=false;
    		return;
    	}
    	int mid=(r+l)>>1,lson=rt<<1,rson=lson+1;
    	build_tree(lson,l,mid);
    	build_tree(rson,mid+1,r);
    	update(rt);
    }
    inline void modify(int rt,int l,int r)
    {
    	if (segment[rt].l<=l&&segment[rt].r>=r)
    	{
    		if (segment[rt].l==l&&segment[rt].r==r)
    		{
    			segment[rt].tag^=1;
    			swap(segment[rt].flash,segment[rt].dark);
    			return;
    		}
    		if (segment[rt].tag)pushdown(rt);
    		int mid=(segment[rt].l+segment[rt].r)>>1,lson=rt<<1,rson=lson+1;
    		if (r<=mid)modify(lson,l,r);
    		else if (l>mid)modify(rson,l,r);
    		else
    		{
    			modify(lson,l,mid);
    			modify(rson,mid+1,r);
    		}
    		update(rt);
    	}
    	return ;
    }
    inline int query(int rt,int l,int r)
    {
    	if (segment[rt].l<=l&&segment[rt].r>=r)
    	{
    		if (segment[rt].l==l&&segment[rt].r==r)
    		{
    			return segment[rt].flash;
    		}
    		if (segment[rt].tag)pushdown(rt);
    		int mid=(segment[rt].l+segment[rt].r)>>1,lson=rt<<1,rson=lson+1;
    		if (r<=mid)return query(lson,l,r);
    		else if (l>=mid+1)return query(rson,l,r);
    		else return query(lson,l,mid)+query(rson,mid+1,r);
    	}
    	return 0;
    }
    

    行吧......

  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/jelly123/p/10390559.html
Copyright © 2011-2022 走看看