zzuli 1731

比赛时写这道题 跟着学长的思路走      咬定就是二维树状数组 结果后来时间从1s加到3s 还是一直超时     想在区域赛的时候夜市死在超时上    到最后也是没能写对这道题     后来听了学弟的思路才恍然大悟    数据这么有规律    完全可以用等差公式求出和    复杂度是O(1 ) 完全没有超时的可能    并且m n 也完全没有发挥作用 1s的时间 用cin读入也能轻轻松松过


公式

a = (xx + yy + x2 + yy) * (x2 - xx + 1) / 2

ans = (a + a + (y2 - yy) * (x2 - xx + 1) ) * (y2 - yy + 1) / 2  

1731: 矩阵

Time Limit: 3 Sec   Memory Limit: 128 MB
Submit: 291   Solved: 33

Submit Status Web Board

Description

Input

Output

Sample Input

1
3 4 4
Q 1 1 1 1
Q 1 1 3 2
M 1 1 3
Q 1 1 3 4

Sample Output

2
21
55

HINT

Source





#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <cmath>
#include <deque>
#include <stack>
#include <cctype>
#include <iomanip>
using namespace std;

typedef long long ll;
typedef long double ld;

const int N = 1100;
const int INF = 0xfffffff;
const double EPS = 1e-8;
const ll MOD = 1e9 + 7;
const ld PI = 4 * atan(1.0);

#define INFL 0x7fffffffffffffffLL
#define met(a, b) memset(a, b, sizeof(a))
#define rep(c, a, b) for (int c = a; c < b; c++)
#define nre(c, a, b) for (int c = a; c > b; c--)
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a)

int xx, yy, x2, y2;

struct node
{
    int x, y, z;
} stu[N];

ll solve (ll ans, int f);

int main ()
{
    int k;
    cin >> k;
    while (k--)
    {
        int m, n, t, f = 0;
        cin >> m >> n >> t;
        while (t--)
        {
            char ch;
            cin >> ch >> xx >> yy;

            if (ch == 'Q')
            {
                cin >> x2 >> y2;
                ll a = (xx + yy + x2 + yy) * (x2 - xx + 1) / 2;
                ll ans = (a + a + (y2 - yy) * (x2 - xx + 1) ) * (y2 - yy + 1) / 2;
                cout << solve(ans, f) << endl;
            }
            else
            {
                cin >> x2;
                int i;
                for (i=0; i<f; i++)
                {
                    if (stu[i].x == xx && stu[i].y == yy)
                        {stu[i].z = x2; break;}
                }
                if (i == f) stu[f++] = {xx, yy, x2};
            }
        }
    }
    return 0;
}

ll solve (ll ans, int f)
{
    for (int i=0; i<f; i++)
    {
        if (stu[i].x >= xx && stu[i].x <= x2 && stu[i].y >= yy && stu[i].y <= y2)
            ans = ans - stu[i].x - stu[i].y + stu[i].z;
    }
    return ans;
}



看题解上面说可以用二维树状数组 简单暴力 

我就试着写了一下 居然1a  用cin读入 才990ms 顿时心情变得无比悲愤 我只想说 我去上厕所 不要动键盘


#include <iostream> 
#include <algorithm> 
#include <queue> 
#include <cstring> 
#include <cstdio> 
#include <vector> 
#include <string> 
#include <iterator> 
#include <cmath> 
#include <deque> 
#include <stack> 
#include <cctype> 
#include <iomanip> 
#include <stack> 
using namespace std; 
  
typedef long long ll; 
typedef long double ld; 
  
const int N = 1100; 
const int INF = 0xfffffff; 
const double EPS = 1e-8; 
const ll MOD = 1e9 + 7; 
const ld PI = 4 * atan(1.0); 
  
#define INFL 0x7fffffffffffffffLL 
#define met(a, b) memset(a, b, sizeof(a)) 
#define rep(c, a, b) for (int c = a; c < b; c++) 
#define nre(c, a, b) for (int c = a; c > b; c--) 
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a) 
  
int m, n, aa[N][N], ans[N][N], aa1[N][N], ans1[N][N]; 
  
void init (); 
int lowbit (int x); 
void add (int x, int y, int z); 
int sum (int x, int y); 
void add1 (int x, int y, int z); 
  
int main () 
{ 
    int k, t; 
    cin >> k; 
    init (); 
    while (k--) 
    { 
        memcpy (aa, aa1, sizeof(aa1)); 
        memcpy (ans, ans1, sizeof(ans1)); 
        cin >> m >> n >> t; 
        while (t--) 
        { 
            char ch; 
            int a, b, c, d; 
            cin >> ch >> a >> b; 
            if (ch == 'Q') 
            { 
                cin >> c >> d; 
                cout << sum (c, d) + sum (a-1, b-1) - sum(c, b-1) - sum (a-1, d) << endl; 
            } 
            else
            { 
                cin >> c; 
                add (a, b, c); 
                aa[a][b] = c; 
            } 
        } 
    } 
    return 0; 
} 
  
int lowbit (int x) 
{ 
    return x & (-x); 
} 
  
void add (int x, int y, int z) 
{ 
    for (int i=x; i<=m; i+=lowbit(i)) 
        for (int j=y; j<=n; j+=lowbit(j)) 
            ans[i][j] = ans[i][j] - aa[x][y] + z; 
} 
  
int sum (int x, int y) 
{ 
    int res = 0; 
    for (int i=x; i>=1; i-=lowbit(i)) 
        for (int j=y; j>=1; j-=lowbit(j)) 
            res += ans[i][j]; 
    return res; 
} 
  
void init () 
{ 
    met (ans1, 0); 
    for (int i=1; i<N; i++) 
        for (int j=1; j<N; j++) 
        { 
            aa1[i][j] = i + j; 
            add1 (i, j, i+j); 
        } 
} 
  
void add1 (int x, int y, int z) 
{ 
    for (int i=x; i<N; i+=lowbit(i)) 
        for (int j=y; j<N; j+=lowbit(j)) 
            ans1[i][j] +=  z; 
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值