• 【wikioi】1690 开关灯(线段树)


    http://wikioi.com/problem/1690/

    这题可不能算是水题了。。

    在线段树中,我只想到了lazy改变,但是没想到lazy变后size怎么变,我的策略变成了lazy为0时size也为0.。这显然不科学啊。

    根据加加减减,s=A-s 的方法正好可以表示开关灯剩余的数量。

    我没想到啊!!!!!!

    还好,,,做到了一题这种题,如果考场上出我做错,那么天杀的啊!!!

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define rep(i, n) for(int i=0; i<(n); ++i)
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    #define for2(i,a,n) for(int i=(a);i<(n);++i)
    #define for3(i,a,n) for(int i=(a);i>=(n);--i)
    #define for4(i,a,n) for(int i=(a);i>(n);--i)
    #define CC(i,a) memset(i,a,sizeof(i))
    #define read(a) a=getint()
    #define print(a) printf("%d", a)
    #define dbg(x) cout << #x << " = " << x << endl
    #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
    inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
    inline const int max(const int &a, const int &b) { return a>b?a:b; }
    inline const int min(const int &a, const int &b) { return a<b?a:b; }
    
    #define lc x<<1
    #define rc x<<1|1
    #define MID (l+r)>>1
    #define lson l, m, lc
    #define rson m+1, r, rc
    const int N=200005;
    int s[N*10], L, R, n;
    bool add[N*10];
    inline void pushup(const int &x) { s[x]=s[lc]+s[rc]; }
    inline void pushdown(const int &x, const int &m) {
    	if(add[x]) {
    		add[lc]^=1; add[rc]^=1;
    		s[lc]=(m-(m>>1))-s[lc];
    		s[rc]=(m>>1)-s[rc];
    		add[x]=0;
    	}
    }
    void update(const int &l, const int &r, const int &x) {
    	if(L<=l && r<=R) { add[x]^=1; s[x]=r-l+1-s[x]; return; }
    	pushdown(x, r-l+1);
    	int m=MID;
    	if(L<=m) update(lson); if(m<R) update(rson);
    	pushup(x);
    }
    int query(const int &l, const int &r, const int &x) {
    	if(L<=l && r<=R) return s[x];
    	pushdown(x, r-l+1);
    	int m=MID, ret=0;
    	if(L<=m) ret+=query(lson); if(m<R) ret+=query(rson);
    	pushup(x);
    	return ret;
    }
    int main() {
    	read(n);
    	int m=getint(), cs;
    	while(m--) {
    		read(cs); read(L); read(R);
    		if(!cs) update(1, n, 1);
    		else printf("%d
    ", query(1, n, 1));
    	}	
    	return 0;
    }
    

        YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m& lt;=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1& lt;=i,j,x,y<=N)

    第 1 行: 用空格隔开的两个整数N和M
    第 2..M+1 行: 每行表示一个操作, 有三个用空格分开的整数: 指令号(0代表按下开关,1代表询问状态), x 和 y 

    第 1..询问总次数 行:对于每一次询问,输出询问的结果

    4 5
    0 1 2
    0 2 4
    1 2 3
    0 2 4
    1 1 4

    1
    2
     

    一共4盏灯,5个操作,下面是每次操作的状态(X代表关上的,O代表开着的):

    XXXX -> OOXX -> OXOO -> 询问1~3 -> OOXX -> 询问1~4

  • 相关阅读:
    jQuery函数继承 $.extend, $.fn.extend
    [原创]茗洋AaronYang的 jquery.myselect.js 我的一次前端突破[上]
    EasyUI 的 combotree 加载数据后折叠起来,并且只允许单击子节点的写法
    判断js数组包是否包含某个元素
    JS中 HTMLEncode和HTMLDecode
    Easyui datagrid 特殊处理,记录笔记
    easyui tab上面添加右键菜单
    第三方文本框 在div中显示预览,让指定节点不受外部css影响
    Easyui 让Window弹出居中
    C# txt格式记录时间,时间对比,决定是否更新代码记录Demo
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3932526.html
Copyright © 2020-2023  润新知