• Codeforces 707 E. Garlands (二维树状数组)


    题目链接:http://codeforces.com/problemset/problem/707/E

    给你nxm的网格,有k条链,每条链上有len个节点,每个节点有一个值。

    有q个操作,操作ask问你一个子矩阵的和是多少,操作switch将第i条链上的值0变原来的数or原来的数变0。

    比较明显的二维数组数组暴力,注意的是ask操作不会超过2000,所以在switch操作的时候不能进行update操作,否则会超时。所以你在ask操作的时候update就会省时。

    复杂度大概是2000*2000*log2(2000)*log2*(2000),cf上3s妥妥过。

     1 //#pragma comment(linker, "/STACK:102400000, 102400000")
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <ctime>
    10 #include <list>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef pair <int, int> P;
    16 const int N = 2e3 + 5;
    17 int n, m;
    18 LL bit[N][N];
    19 struct data {
    20     int x[N], y[N], w[N], len;
    21 }a[N];
    22 bool change[N];
    23 int flag[N];
    24 
    25 void update(int x, int y, LL val) {
    26     for(int i = x; i <= n; i += (i&-i)) {
    27         for(int j = y; j <= m; j += (j&-j)) {
    28             bit[i][j] += val;
    29         }
    30     }
    31 }
    32 
    33 LL sum(int x, int y) {
    34     LL s = 0;
    35     for(int i = x; i >= 1; i -= (i&-i)) {
    36         for(int j = y; j >= 1; j -= (j&-j)) {
    37             s += bit[i][j];
    38         }
    39     }
    40     return s;
    41 }
    42 
    43 int main()
    44 {
    45     int k, q;
    46     scanf("%d %d %d", &n, &m, &k);
    47     for(int i = 1; i <= k; ++i) {
    48         scanf("%d", &a[i].len);
    49         for(int j = 1; j <= a[i].len; ++j) {
    50             scanf("%d %d %d", &a[i].x[j], &a[i].y[j], &a[i].w[j]);
    51             update(a[i].x[j], a[i].y[j], (LL)a[i].w[j]);
    52         }
    53     }
    54     scanf("%d", &q);
    55     char query[10];
    56     int x1, y1, x2, y2, c;
    57     for(int i = 1; i <= q; ++i) {
    58         scanf("%s", query);
    59         if(query[0] == 'A') {
    60             scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
    61             for(int id = 1; id <= k; ++id) {
    62                 if(change[id]) {
    63                     if(flag[id] % 2) {
    64                         for(int j = 1; j <= a[id].len; ++j) {
    65                             update(a[id].x[j], a[id].y[j], (LL)a[id].w[j]);
    66                         }
    67                     } else {
    68                         for(int j = 1; j <= a[id].len; ++j) {
    69                             update(a[id].x[j], a[id].y[j], (LL)-a[id].w[j]);
    70                         }
    71                     }
    72                     change[id] = change[id] ? false: true;
    73                     ++flag[id];
    74                 }
    75             }
    76             printf("%lld
    ", sum(x2, y2) - sum(x2, y1 - 1) - sum(x1 - 1, y2) + sum(x1 - 1, y1 - 1));
    77         } else {
    78             scanf("%d", &c);
    79             change[c] = change[c] ? false: true;
    80         }
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    如何避免重复的开发
    用BPM解决企业信息化的数据孤岛
    撸代码之前我们应该想些什么
    从开发的角度去分解项目需求
    MQTT 无法连接问题排查
    Linux下的OpenSSH,你知道多少?
    Linux下Rsyslog日志远程集中式管理
    如何在Linux下部署Samba服务?
    Linux环境下安装配置vsftpd服务(三种认证模式)
    Linux集群环境下NTP服务器时间同步
  • 原文地址:https://www.cnblogs.com/Recoder/p/5845708.html
Copyright © 2020-2023  润新知