zoukankan      html  css  js  c++  java
  • hdu 3397 Sequence operation 线段树

    题目链接

    给出n个数, 每个数是0或1, 给5种操作, 区间变为1, 区间变为0, 区间0,1翻转, 询问区间内1的个数, 询问区间内最长连续1的个数。

    需要将数组开成二维的, 然后区间0, 1翻转只需要交换一个数组的第二维就可以。

    一个数组记录区间最长, 一个记录前缀, 一个记录后缀, 一个记录总数, 一个lazy标记, 一个xor标记。

    如果遇到覆盖的情况, 那么这个区间如果原先有xor标记, 那么直接将xor清零。

    这个题我写的代码可能不太适合人类观看............

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define pb(x) push_back(x)
      4 #define ll long long
      5 #define mk(x, y) make_pair(x, y)
      6 #define lson l, m, rt<<1
      7 #define mem(a) memset(a, 0, sizeof(a))
      8 #define rson m+1, r, rt<<1|1
      9 #define mem1(a) memset(a, -1, sizeof(a))
     10 #define mem2(a) memset(a, 0x3f, sizeof(a))
     11 #define rep(i, a, n) for(int i = a; i<n; i++)
     12 #define ull unsigned long long
     13 typedef pair<int, int> pll;
     14 const double PI = acos(-1.0);
     15 const double eps = 1e-8;
     16 const int mod = 1e9+7;
     17 const int inf = 1061109567;
     18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
     19 const int maxn = 1e5+5;
     20 int maxx[maxn<<2][2], pre_max[maxn<<2][2], suf_max[maxn<<2][2], XOR[maxn<<2], lazy[maxn<<2], sum[maxn<<2][2];
     21 void pushUp(int rt, int sign, int m) {
     22     maxx[rt][sign] = max(maxx[rt<<1][sign], maxx[rt<<1|1][sign]);
     23     pre_max[rt][sign] = pre_max[rt<<1][sign];
     24     suf_max[rt][sign] = suf_max[rt<<1|1][sign];
     25     sum[rt][sign] = sum[rt<<1][sign]+sum[rt<<1|1][sign];
     26     if(pre_max[rt][sign] == (m-(m>>1)))
     27         pre_max[rt][sign] += pre_max[rt<<1|1][sign];
     28     if(suf_max[rt][sign] == (m>>1))
     29         suf_max[rt][sign] += suf_max[rt<<1][sign];
     30     maxx[rt][sign] = max(maxx[rt][sign], suf_max[rt<<1][sign]+pre_max[rt<<1|1][sign]);
     31 }
     32 void change(int rt) {
     33         swap(sum[rt][0], sum[rt][1]);
     34         swap(maxx[rt][0], maxx[rt][1]);
     35         swap(pre_max[rt][0], pre_max[rt][1]);
     36         swap(suf_max[rt][0], suf_max[rt][1]);
     37         XOR[rt]^=1;
     38 }
     39 void pushDown(int rt, int m) {
     40     if(~lazy[rt]) {
     41         XOR[rt<<1] = XOR[rt<<1|1] = 0;
     42         int sign = lazy[rt];
     43         maxx[rt<<1][sign] = sum[rt<<1][sign] = pre_max[rt<<1][sign] = suf_max[rt<<1][sign] = (m-(m>>1));
     44         maxx[rt<<1|1][sign] = sum[rt<<1|1][sign] = pre_max[rt<<1|1][sign] = suf_max[rt<<1|1][sign] = (m>>1);
     45         sign^=1;
     46         maxx[rt<<1][sign] = sum[rt<<1][sign] = pre_max[rt<<1][sign] = suf_max[rt<<1][sign] = 0;
     47         maxx[rt<<1|1][sign] = sum[rt<<1|1][sign] = pre_max[rt<<1|1][sign] = suf_max[rt<<1|1][sign] = 0;
     48         lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
     49         lazy[rt] = -1;
     50     }
     51     if(XOR[rt]) {
     52         change(rt<<1);
     53         change(rt<<1|1);
     54         XOR[rt] = 0;
     55     }
     56 }
     57 void build(int l, int r, int rt) {
     58     XOR[rt] = 0, lazy[rt] = -1;
     59     if(l == r) {
     60         int sign;
     61         scanf("%d", &sign);
     62         sum[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = maxx[rt][sign] = 1;
     63         sign^=1;
     64         sum[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = maxx[rt][sign] = 0;
     65         return ;
     66     }
     67     int m = l+r>>1;
     68     build(lson);
     69     build(rson);
     70     pushUp(rt, 1, r-l+1);
     71     pushUp(rt, 0, r-l+1);
     72 }
     73 void update(int L, int R, int l, int r, int rt, int sign) {
     74     if(L<=l&&R>=r) {
     75         if(sign == 2) {
     76             change(rt);
     77         } else {
     78             lazy[rt] = sign;
     79             sum[rt][sign] = maxx[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = (r-l+1);
     80             sign ^= 1;
     81             sum[rt][sign] = maxx[rt][sign] = pre_max[rt][sign] = suf_max[rt][sign] = 0;
     82             XOR[rt] = 0;
     83         }
     84         return ;
     85     }
     86     pushDown(rt, r-l+1);
     87     int m = l+r>>1;
     88     if(L<=m)
     89         update(L, R, lson, sign);
     90     if(R>m)
     91         update(L, R, rson, sign);
     92     pushUp(rt, 0, r-l+1);
     93     pushUp(rt, 1, r-l+1);
     94 }
     95 int query(int L, int R, int l, int r, int rt, int sign) {
     96     if(L<=l&&R>=r) {
     97         if(sign) {
     98             return maxx[rt][1];
     99         } else {
    100             return sum[rt][1];
    101         }
    102     }
    103     pushDown(rt, r-l+1);
    104     int m = l+r>>1, ret = 0;
    105     if(sign) {
    106         if(L<=m)
    107             ret = query(L, R, lson, sign);
    108         if(R>m)
    109             ret = max(ret, query(L, R, rson, sign));
    110         ret = max(ret, min(R-m, pre_max[rt<<1|1][1])+min(m-L+1, suf_max[rt<<1][1]));
    111         return ret;
    112     } else {
    113         if(L<=m)
    114             ret += query(L, R, lson, sign);
    115         if(R>m)
    116             ret += query(L, R, rson, sign);
    117         return ret;
    118     }
    119 }
    120 int main()
    121 {
    122     int t, n, m, sign, x, y;
    123     cin>>t;
    124     while(t--) {
    125         scanf("%d%d", &n, &m);
    126         build(1, n, 1);
    127         while(m--) {
    128             scanf("%d%d%d", &sign, &x, &y);
    129             if(sign <= 2) {
    130                 update(x+1, y+1, 1, n, 1, sign);
    131             } else {
    132                 cout<<query(x+1, y+1, 1, n, 1, sign-3)<<endl;
    133             }
    134         }
    135     }
    136 }
  • 相关阅读:
    ios webapp调试神器MIHTool
    20个正则表达式
    jQuery技巧
    浏览器判断和移动端的判断
    JavaScript 被忽视的细节
    移动端Web页面问题解决方案
    virtualenv创建虚拟环境
    init.d文件夹
    python連接mysql數據庫
    const和define的使用区别
  • 原文地址:https://www.cnblogs.com/yohaha/p/5042637.html
Copyright © 2011-2022 走看看