zoukankan      html  css  js  c++  java
  • codeforces 400E. Inna and Binary Logic 线段树

    题目链接

    给出n个数, 定义a[1][i]为这初始的n个数, 然后a[i][j] = a[i-1][j]&a[i-1][j-1], 这样就可以得到一个三角形一共n*(n-1)/2个数。

    给出一种操作, 将a[1][x]这个位置的数换为y, 然后求换完之后的这n(n-1)/2个数的和。

    很有意思的题, 这个题应该按位建线段树, 这样需要建18棵, 因为a[1][i]的最大值为1e5。

    然后我们来看具体如何做, 我们来看一组数据:3 6 7, 换为二进制之后是下面这个样子。

    0 1 1

    1 1 0

    1 1 1

    我们先来算一算这三个数的值为多少, 3+6+7+2+6+2 = 26。

    我们发现第一个数和第二个数&之后剩余的是2, 第二个数和第三个数&之后剩余的是6, 我们来观察二进制, 发现第一个数和第二个数的第二位的2个1是相邻的, 并且这一位换成10进制正好是2, 而第二个数和第三个数的第一位和第二位的两个1是相邻的, 换成10进制之后是6。

    由此可以推断出, 如果是一个单独的1, 那么贡献就是1, 两个相邻的1贡献是2*3/2 = 3,n个相邻的1贡献就是n(n+1)/2。

    那么我们建立线段树的时候就应该保存一个sum, prefix, 以及suffix, 具体的看代码。

     1 #include <iostream>
     2 #include <vector>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <cmath>
     7 #include <map>
     8 #include <set>
     9 #include <string>
    10 #include <queue>
    11 #include <stack>
    12 #include <bitset>
    13 using namespace std;
    14 #define pb(x) push_back(x)
    15 #define ll long long
    16 #define mk(x, y) make_pair(x, y)
    17 #define lson l, m, rt<<1
    18 #define mem(a) memset(a, 0, sizeof(a))
    19 #define rson m+1, r, rt<<1|1
    20 #define mem1(a) memset(a, -1, sizeof(a))
    21 #define mem2(a) memset(a, 0x3f, sizeof(a))
    22 #define rep(i, n, a) for(int i = a; i<n; i++)
    23 #define fi first
    24 #define se second
    25 typedef pair<int, int> pll;
    26 const double PI = acos(-1.0);
    27 const double eps = 1e-8;
    28 const int mod = 1e9+7;
    29 const int inf = 1061109567;
    30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    31 const int maxn = 1e5+5;
    32 ll cal(ll val) {
    33     return 1LL*val*(val+1)/2;
    34 }
    35 struct SegmentTree
    36 {
    37     ll sum[maxn<<2], pre[maxn<<2], suf[maxn<<2];
    38     void pushUp(int rt, int m) {
    39         sum[rt] = sum[rt<<1|1] + sum[rt<<1];
    40         if(pre[rt<<1|1]&&suf[rt<<1]) {
    41             sum[rt] += cal(pre[rt<<1|1]+suf[rt<<1])-cal(suf[rt<<1])-cal(pre[rt<<1|1]); 
    42         }     
    43         pre[rt] = pre[rt<<1];
    44         suf[rt] = suf[rt<<1|1];
    45         if(pre[rt] == m-(m>>1)) {
    46             pre[rt] += pre[rt<<1|1];
    47         }
    48         if(suf[rt] == m>>1) {
    49             suf[rt] += suf[rt<<1];
    50         }
    51     }
    52     void update(int p, int val, int l, int r, int rt) {
    53         if(l == r) {
    54             sum[rt] = pre[rt] = suf[rt] = val;
    55             return ;
    56         }
    57         int m = l+r>>1;
    58         if(p<=m)
    59             update(p, val, lson);
    60         else
    61             update(p, val, rson);
    62         pushUp(rt, r-l+1);
    63     }
    64 }tree[18];
    65 int main()
    66 {
    67     int cnt, n, m, x, y, a[20];
    68     cin>>n>>m;
    69     for(int i = 1; i<=n; i++) {
    70         scanf("%d", &x);
    71         cnt = 0;
    72         while(x) {
    73             a[cnt++] = x&1;
    74             x>>=1;
    75         }
    76         for(int j = 0; j<cnt; j++) {
    77             tree[j].update(i, a[j], 1, n, 1);
    78         }
    79     }
    80     while(m--) {
    81         scanf("%d%d", &x, &y);
    82         cnt = 0;
    83         mem(a);
    84         while(y) {
    85             a[cnt++] = y&1;
    86             y>>=1;
    87         }
    88         ll ans = 0, mul = 1;
    89         for(int i = 0; i<18; i++) {
    90             tree[i].update(x, a[i], 1, n, 1);
    91             ans += tree[i].sum[1]*mul;
    92             mul*=2;
    93         }
    94         cout<<ans<<endl;
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    LeetCode 1110. Delete Nodes And Return Forest
    LeetCode 473. Matchsticks to Square
    LeetCode 886. Possible Bipartition
    LeetCode 737. Sentence Similarity II
    LeetCode 734. Sentence Similarity
    LeetCode 491. Increasing Subsequences
    LeetCode 1020. Number of Enclaves
    LeetCode 531. Lonely Pixel I
    LeetCode 1091. Shortest Path in Binary Matrix
    LeetCode 590. N-ary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/yohaha/p/5088942.html
Copyright © 2011-2022 走看看