zoukankan      html  css  js  c++  java
  • Loj 【CQOI 2006】简单题,mmp

     

    题目描述

    题目来源:CQOI 2006

    有一个 nnn 个元素的数组,每个元素初始均为 000。有 mmm 条指令,要么让其中一段连续序列数字反转——000 变 111,111 变 000(操作 111),要么询问某个元素的值(操作 222)。

    例如当 n=20n=20n=20 时,101010 条指令如下:

    操作回答操作后的数组
    1 1 101 1 101 1 10 N/A 111111111100000000001111111111000000000011111111110000000000
    2 62 62 6 111 111111‾1111000000000011111underline{1}11110000000000111111​​11110000000000
    2 122 122 12 000 111111111100‾0000000011111111110underline{0}00000000111111111100​​00000000
    1 5 121 5 121 5 12 N/A 111100000011000000001111000000110000000011110000001100000000
    2 62 62 6 000 111100‾0000110000000011110underline{0}00001100000000111100​​00001100000000
    2 152 152 15 000 111100000011000‾0000011110000001100underline 000000111100000011000​​00000
    1 6 161 6 161 6 16 N/A 11110111110011110000 1111011111001111000011110111110011110000
    1 11 171 11 171 11 17 N/A 111101111111000010001111011111110000100011110111111100001000
    2 122 122 12 111 111101111111‾0000100011110111111underline 100001000111101111111​​00001000
    2 62 62 6 111 111101‾1111110000100011110underline 111111100001000111101​​11111100001000

    输入格式

    第一行包含两个整数 n,mn,mn,m,表示数组的长度和指令的条数;
    以下 mmm 行,每行的第一个数 ttt 表示操作的种类:

    • 若 t=1t=1t=1,则接下来有两个数 L,RL, RL,R,表示区间 [L,R][L, R][L,R] 的每个数均反转;
    • 若 t=2t=2t=2,则接下来只有一个数 iii,表示询问的下标。

    输出格式

    每个操作 222 输出一行(非 000 即 111),表示每次操作 222 的回答。

    样例

    样例输入

    20 10
    1 1 10
    2 6
    2 12
    1 5 12
    2 6
    2 15
    1 6 16
    1 11 17
    2 12
    2 6

    样例输出

    1
    0
    0
    0
    1
    1

    数据范围与提示

    对于 50%50\%50% 的数据,1≤n≤103,1≤m≤1041le nle 10^3,1le mle 10^41n103​​,1m104​​;
    对于 100%100\%100% 的数据,1≤n≤105,1≤m≤5×1051le nle 10^5,1le mle 5 imes 10^51n105​​,1m5×105​​,保证 L≤RLle RLR。

    分析

    其实这道题很简单(只要你想得到的话)

    首先区间操作,区间查询,很容易想到 RMQ ,然后树状数组和线段树貌似没有翻转区间信息的功能啊。怎么办呢?

    那么我们考虑一下这道题的性质:最后得到的数字只可能是 0 或 1 也就是说如果某个位置被翻转两遍那么效果是一样的。。。

    然后要非常生硬的联想到位运算 & ... 

    接下来我们这么操作(鉴于树状数组常数小那么就用树状数组的讲法了,至于线段树也就是永久化标记的事儿):

    我们每次直接去加一个区间的左端点 l 以及右端点 r+1 ,那么 r+1 以及后面位置上的数被翻转了两次,最低位还是不变

    查询的时候我们直接单点查询(这里不需要什么骚操作,直接查询 x 的前缀和就好了,因为前面区间没有覆盖到 x 的话必然是向后累加了两次的,效果会抵消)。

    没错,很朴素。没错,很简单。没错,就是想不到。

     

    代码

  • 相关阅读:
    VS2005下安装boost
    NOIP2017宝藏 [搜索/状压dp]
    SCOI2008奖励关 [状压dp]
    莫队算法解析
    SCOI2005 互不侵犯 [状压dp]
    Codeforces ----- Kefa and Dishes [状压dp]
    TSP问题之状压dp法
    NOI2001炮兵阵地 [状压dp]
    状压dp入门
    「网络流24题」餐巾计划问题
  • 原文地址:https://www.cnblogs.com/Judge/p/9630412.html
Copyright © 2011-2022 走看看