• 洛谷 P3870 [TJOI2009]开关


    洛谷 P3870 [TJOI2009]开关

    洛谷传送门

    题目描述

    现有 nn 盏灯排成一排,从左到右依次编号为:11,22,……,nn。然后依次执行 mm 项操作。

    操作分为两种:

    1. 指定一个区间 [a,b][a,b],然后改变编号在这个区间内的灯的状态(把开着的灯关上,关着的灯打开);
    2. 指定一个区间 [a,b][a,b],要求你输出这个区间内有多少盏灯是打开的。

    灯在初始时都是关着的。

    输入格式

    第一行有两个整数 nn 和 mm,分别表示灯的数目和操作的数目。

    接下来有 mm 行,每行有三个整数,依次为:cc、aa、bb。其中 cc 表示操作的种类。

    • 当 cc 的值为 00 时,表示是第一种操作。
    • 当 cc 的值为 11 时,表示是第二种操作。

    aa 和 bb 则分别表示了操作区间的左右边界。

    输出格式

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


    题解:

    多种数据结构的练手题。

    我是为了练分块才来做的这道题。以前一直以为自己会写分块,但是很多细节的部分还是不太会维护。

    代码:

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn=1e5+5;
    int n,m;
    int block;
    int a[maxn],b[maxn];
    int ans[maxn],lazy[maxn];
    void update(int x,int y)
    {
        for(int i=x;i<=min(y,b[x]*block);i++)
        {
            ans[b[x]]-=a[i]^lazy[b[x]];
            a[i]^=1;
            ans[b[x]]+=a[i]^lazy[b[x]];
        }
        if(b[x]!=b[y])
        {
            for(int i=(b[y]-1)*block+1;i<=y;i++)
            {
                ans[b[y]]-=a[i]^lazy[b[y]];
                a[i]^=1;
                ans[b[y]]+=a[i]^lazy[b[y]];
            }
        }
        for(int i=b[x]+1;i<=b[y]-1;i++)
        {
            lazy[i]^=1;
            ans[i]=block-ans[i];
        }
    }
    int query(int x,int y)
    {
        int ret=0;
        for(int i=x;i<=min(y,b[x]*block);i++)
            ret+=a[i]^lazy[b[i]];
        if(b[x]!=b[y])
            for(int i=(b[y]-1)*block+1;i<=y;i++)
                ret+=a[i]^lazy[b[y]];
        for(int i=b[x]+1;i<=b[y]-1;i++)
            ret+=ans[i];
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        block=sqrt(n);
        for(int i=1;i<=n;i++)
            b[i]=(i-1)/block+1;//注意是i-1
        for(int i=1;i<=m;i++)
        {
            int opt,x,y;
            scanf("%d%d%d",&opt,&x,&y);
            if(!opt)
                update(x,y);
            else
                printf("%d
    ",query(x,y));
        }
        return 0;
    }
    
  • 相关阅读:
    poj_1084 剪枝-IDA*
    搜索算法
    poj_1475 BFS+BFS
    chrome浏览器经常无响应
    charles抓包工具的使用:手机抓包设置和安装证书
    charles抓包工具的使用:概述
    不同局域网如何利用charles对app进行抓包
    fiddler之使用教程(一)
    一点感触
    单元测试框架处理多组数据的另一种写法:基于构造函数和超继承
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14043013.html
Copyright © 2020-2023  润新知