zoukankan      html  css  js  c++  java
  • 洛谷 P3870 [TJOI2009]开关

    题意简述

    有n盏灯,默认为关,有两个操作:
    1.改变l~r的灯的状态(把开着的灯关上,关着的灯打开)
    2.查询l~r开着的灯的数量

    题解思路

    维护一个线段树,支持区间修改,区间查询
    懒标记每次^1

    代码

    #include <cstdio>
    using namespace std;
    int n, m, opt, x, y;
    int a[400010], la[400010];
    void push_up(int x)
    {
    	a[x] = a[x << 1] + a[x << 1 | 1];
    }
    void push_down(int x, int len)
    {
    	a[x << 1] = (len - (len >> 1)) - a[x << 1];
    	a[x << 1 | 1] = (len >> 1) - a[x << 1 | 1];
    	la[x << 1] ^= 1;
    	la[x << 1 | 1] ^= 1;
    	la[x] = 0;
    }
    void change(int x, int l, int r, int l1, int r1)
    {
    	if (l1 <= l && r <= r1)
    	{
    		a[x] = r - l + 1 - a[x];
    		la[x] ^= 1;
    		return;
    	}
    	if (la[x]) push_down(x, r - l + 1);
    	int mid = l + r >> 1;
    	if (l1 <= mid) change(x << 1, l, mid, l1, r1);
    	if (r1 >  mid) change(x << 1 | 1, mid + 1, r, l1, r1);
    	push_up(x); 
    }
    int query(int x, int l, int r, int l1, int r1, int ans = 0)
    {
    	if (l1 <= l && r <= r1)	return a[x];
    	if (la[x]) push_down(x, r - l + 1);
    	int mid = l + r >> 1;
    	if (l1 <= mid) ans += query(x << 1, l, mid, l1, r1);
    	if (r1 >  mid) ans += query(x << 1 | 1, mid + 1, r, l1, r1);
    	return ans;
    }
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for (register int i = 1; i <= m; ++i)
    	{
    		scanf("%d", &opt);
    		if (!opt)
    		{
    			scanf("%d%d", &x, &y);
    			change(1, 1, n, x, y);
    		}
    		else
    		{
    			scanf("%d%d", &x, &y);
    			printf("%d
    ", query(1, 1, n, x, y));
    		}
    	}
    }
    
  • 相关阅读:
    扩展正则表达式 练习题
    Linux特殊符号
    文件属性下
    文件属性和ls -lhi
    复习之前的和补充一些内容
    第二关练习题总结完结
    云服务器防ssh攻击
    实验四+085
    实验3+085
    第5次作业+085
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9477707.html
Copyright © 2011-2022 走看看