• BZOJ 1176: [Balkan2007]Mokia


    1176: [Balkan2007]Mokia

    Time Limit: 30 Sec  Memory Limit: 162 MB
    Submit: 2012  Solved: 896
    [Submit][Status][Discuss]

    Description

    维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.

    Input

    第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小

    接下来每行为一下三种输入之一(不包含引号):

    "1 x y a"

    "2 x1 y1 x2 y2"

    "3"

    输入1:你需要把(x,y)(第x行第y列)的格子权值增加a

    输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出

    输入3:表示输入结束

    Output

    对于每个输入2,输出一行,即输入2的答案

    Sample Input

    0 4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3

    Sample Output

    3
    5

    HINT

    保证答案不会超过int范围

    Source

     
    [Submit][Status][Discuss]

    CDQ分治。

     1 #include <bits/stdc++.h>
     2 const int maxn = 400005;
     3 const int maxw = 2000005;
     4 int tr[maxw], w;
     5 inline void add(int t, int k) {
     6     for (; t <= w; t += t&-t)
     7         tr[t] += k;
     8 }
     9 inline int ask(int t) {
    10     int ret = 0;
    11     for (; t; t -= t&-t)
    12         ret += tr[t];
    13     return ret;
    14 }
    15 inline int ask(int a, int b) {
    16     return ask(b) - ask(a - 1);
    17 }
    18 struct data {
    19    int k, a, b, c, d, t, p; 
    20 }s[maxn]; int tot = 1;
    21 int ans[maxn], cnt = 1;
    22 inline void add(void) {
    23     scanf("%d%d%d", &s[tot].a, &s[tot].b, &s[tot].c), s[tot].t = tot, s[tot++].k = 1;
    24 }
    25 inline void qry(void) {
    26     int x1, x2, y1, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); --x1;
    27     s[tot].k = 2, s[tot].a = x1, s[tot].b = y1, s[tot].c = y2, s[tot].d = -1, s[tot].t = tot, s[tot++].p = cnt;
    28     s[tot].k = 2, s[tot].a = x2, s[tot].b = y1, s[tot].c = y2, s[tot].d = +1, s[tot].t = tot, s[tot++].p = cnt++;
    29 }
    30 inline bool cmp(const data &a, const data &b) {
    31     if (a.a != b.a)return a.a < b.a;
    32     else return a.k < b.k;
    33 }
    34 void solve(int l, int r) {
    35     if (l >= r)return;
    36     int mid = (l + r) >> 1;
    37     solve(l, mid); solve(mid + 1, r);
    38     std::sort(s + l, s + r + 1, cmp);
    39     for (int i = l; i <= r; ++i)
    40         if (s[i].k == 1 && s[i].t <= mid)
    41             add(s[i].b, s[i].c);
    42         else if (s[i].k == 2 && s[i].t > mid)
    43             ans[s[i].p] += ask(s[i].b, s[i].c) * s[i].d;
    44     for (int i = l; i <= r; ++i)
    45         if (s[i].k == 1 && s[i].t <= mid)
    46             add(s[i].b, -s[i].c);
    47 }
    48 signed main(void) {
    49     scanf("%*d%d", &w);
    50     int k; while (scanf("%d", &k), k != 3)
    51         (k == 1) ? add() : qry();
    52     solve(1, tot - 1);
    53     for (int i = 1; i < cnt; ++i)
    54         printf("%d
    ", ans[i]);
    55 }

    @Author: YouSiki

  • 相关阅读:
    CF 1047 C
    POJ 1064 Cable master [二分]
    HDU 1257最少拦截系统[动态规划]
    CF 1096D Easy Problem [动态规划]
    CF 1095C Powers Of Two
    POJ 1O17 Packets [贪心]
    POJ 3273 Monthly Expense二分查找[最小化最大值问题]
    HDU 2037 今年暑假不AC[贪心]
    Machine Learning Stanford (week 3)
    matlab 函数笔记
  • 原文地址:https://www.cnblogs.com/yousiki/p/6242766.html
Copyright © 2020-2023  润新知