zoukankan      html  css  js  c++  java
  • 牛客-牛牛的Link Power II

    题目传送门

    sol:可以用线段树来维护,线段树的节点除了标配的$l$和$r$同时记录该区间$link$的个数记为$cnt$,该区间$link$点的和记为$sum$,该区间题目中所谓的能量记为$dis$。然后$cnt$和$sum$就直接两个儿子相加就好,$dis$还要另外加上$segTree[rs].sum * segTree[ls].cnt - segTree[ls].sum * segTree[rs].cnt$这部分。

    • 线段树
      #include <bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      typedef pair<int, int> PII;
      const int MAXN = 1e5 + 10;
      const int MOD = 1e9 + 7;
      struct Node {
          int l, r;
          int cnt;
          int sum, dis;
      } segTree[4 * MAXN];
      void push_up(int i) {
          int ls = i << 1, rs = i << 1 | 1;
          segTree[i].cnt = segTree[ls].cnt + segTree[rs].cnt;
          segTree[i].sum = (segTree[ls].sum + segTree[rs].sum) % MOD;
          segTree[i].dis = (1LL * segTree[rs].sum * segTree[ls].cnt - 1LL * segTree[ls].sum * segTree[rs].cnt) % MOD;
          segTree[i].dis = (1LL * MOD + segTree[i].dis + segTree[ls].dis + segTree[rs].dis) % MOD;
      }
      void build(int i, int l, int r) {
          segTree[i].l = l;
          segTree[i].r = r;
          if (l == r) {
              int k = getchar() ^ '0';
              segTree[i].cnt = k;
              segTree[i].sum = k * l;
              return;
          }
          int mid = l + r >> 1;
          build(i << 1, l, mid);
          build(i << 1 | 1, mid + 1, r);
          push_up(i);
      }
      void update(int i, int k, int data) {
          if (segTree[i].l == segTree[i].r) {
              segTree[i].cnt = data;
              segTree[i].sum = data * segTree[i].l;
              return;
          }
          int mid = segTree[i].l + segTree[i].r >> 1;
          if (k <= mid) update(i << 1, k, data);
          else update(i << 1 | 1, k, data);
          push_up(i);
      }
      int main() {
          int n; scanf("%d%*c", &n);
          build(1, 1, n);
          printf("%d
      ", segTree[1].dis);
          int q; scanf("%d", &q);
          while (q--) {
              int op, k;
              scanf("%d%d", &op, &k);
              if (op == 1) update(1, k, 1);
              else update(1, k, 0);
              printf("%d
      ", segTree[1].dis);
          }
          return 0;
      }

      这个线段树如果要查询某个区间的dis其实不大好写,但是题目中所有的查询都是针对整棵树,也就是segTree[1]。所以省掉了询问函数。

  • 相关阅读:
    Java内存管理以及各个内存区域详解
    python数据的存储和持久化操作
    Redis的安装及配置
    POI使用详解
    遍历Map的几种方法
    Quartz的cronTrigger表达式
    Java对XML文档的增删改查
    Solr系列二:Solr与mmseg4j的整合
    cms STW 的两个阶段
    GROUP BY 和 ORDER BY 同时使用问题
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/12288701.html
Copyright © 2011-2022 走看看