zoukankan      html  css  js  c++  java
  • 洛谷P2574 XOR的艺术

    题目

    其实跟线段树1,2差不多,唯一需要区别的就是lazy数组及标记下传时候的操作了。

    线段树左儿子的个数应该是比右儿子的个数大的。所以我们需要再将区间异或时,一定要搞清楚每个区间的元素有多少个,然后再将该区间元素的0,1个数颠倒一下就好了

    #include <bits/stdc++.h>			
    #define ll long long				
    #define ls l, mid, root << 1		
    #define rs mid + 1, r, root << 1 | 1
    using namespace std;				
    int n, m, ans[800100], a[800100], lazy[800100];//ans表示一个根节点下1的个数 
    inline void pushup(int root)
    {
    	ans[root] = ans[root << 1] + ans[root << 1 | 1];
    }
    inline void build(int l, int r, int root)
    {
    	if (l == r)
    	{
    		ans[root] = a[l];
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(ls), build(rs);
    	pushup(root);
    }
    inline void pushdown(int l, int r, int root)
    {
    	int mid = (l + r) >> 1;
    	int len = r - l + 1;   
    	if (lazy[root])		  //如果该节点还没有异或1,那就异或 
    	{
    		lazy[root << 1] ^= 1;
    		lazy[root << 1 | 1] ^= 1;
    		ans[root << 1] = len - (len >> 1) - ans[root << 1];//当然还需要更新,原root<<1里有len-len>>1个数。 
    		ans[root << 1 | 1] = (len >> 1) - ans[root << 1 | 1];
    		lazy[root] = 0;
    	}
    }
    void update(int l, int r, int root, int ql, int qr)
    {
    	int len = r - l + 1;
    	if (ql <= l && r <=  qr)
    	{
            lazy[root] ^= 1;
    		ans[root] = len  - ans[root];
            return;
    	}
    	int mid = (l + r) >> 1;
    	pushdown(l, r, root);
    	if (ql <= mid)
    	update(ls, ql, qr);
    	if (qr >= mid + 1)
    	update(rs, ql, qr);
    	pushup(root);
    }
    int query(int l, int r, int root, int ql, int qr)
    {
     	int res = 0;
       	if (ql <= l && r <= qr)
       		return ans[root];
    	int mid = (l + r) >> 1;
    	pushdown(l, r, root);
    	if (ql <= mid)
    	res += query(ls, ql, qr);
    	if (qr >= mid + 1)
    	res += query(rs, ql, qr);
    	return res;
    }
    int main()
    {
    	cout << (5 >> 1);
    	return 0; 
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++)
    	{
    		char c;
            cin >> c;
    		a[i] = c - '0';
    	}
    	build(1, n, 1);
    	while (m--)
    	{
    		int p, l, r;
    		cin >> p >> l >> r;
    		if (p)
    			printf("%d
    ", query(1, n, 1, l, r));
    		else
    			update(1, n, 1, l, r);
    	}
    	return 0;
    }
    
  • 相关阅读:
    php优秀框架codeigniter学习系列——安装,配置
    设计模式学习系列——桥接模式
    elasticsearch学习笔记——相关插件和使用场景
    elasticsearch学习笔记——安装,初步使用
    设计模式学习系列——适配器模式
    php优秀框架codeigniter学习系列——前言
    设计模式学习系列——原型模式
    angular 自定义指令 directive transclude 理解
    inq to datatable group by 多列 实现
    CSS3 media 入门
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/11348451.html
Copyright © 2011-2022 走看看