fafu 1100 线段树

题目链接

单点更新, 区间查询。 这题空间好小....

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, a, n) for(int i = a; i<n; i++)
#define ull unsigned long long
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1050;
int sum[maxn*3][maxn*3], n;
void pushUp(int pos, int rt) {
    sum[pos][rt] = sum[pos][rt<<1]+sum[pos][rt<<1|1];
}
void sub_update(int sign, int pos, int p, int l, int r, int rt, int val) {
    if(l == r) {
        if(!sign) {
            sum[pos][rt] += val;
        } else {
            sum[pos][rt] = sum[pos<<1][rt] + sum[pos<<1|1][rt];
        }
        return ;
    }
    int m = l+r>>1;
    if(p<=m)
        sub_update(sign, pos, p, lson, val);
    else
        sub_update(sign, pos, p, rson, val);
    pushUp(pos, rt);
}
void update(int x, int y, int l, int r, int rt, int val) {
    if(l == r) {
        sub_update(0, rt, y, 1, n, 1, val);
        return ;
    }
    int m = l+r>>1;
    if(x<=m)
        update(x, y, lson, val);
    else
        update(x, y, rson, val);
    sub_update(1, rt, y, 1, n, 1, val);
}
int sub_query(int pos, int L, int R, int l, int r, int rt) {
    if(L<=l&&R>=r) {
        return sum[pos][rt];
    }
    int m = l+r>>1, ret = 0;
    if(L<=m)
        ret += sub_query(pos, L, R, lson);
    if(R>m)
        ret += sub_query(pos, L, R, rson);
    return ret;
}
int query(int lx, int rx, int ly, int ry, int l, int r, int rt) {
    if(lx<=l&&rx>=r) {
        return sub_query(rt, ly, ry, 1, n, 1);
    }
    int m = l+r>>1, ret = 0;
    if(lx<=m)
        ret += query(lx, rx, ly, ry, lson);
    if(rx>m)
        ret += query(lx, rx, ly, ry, rson);
    return ret;
}
int main()
{
    int sign, lx, ly, val, rx, ry, tmp;
    while(~scanf("%*d%d", &n)) {
        mem(sum);
        while(scanf("%d", &sign)) {
            if(sign == 3)
                break;
            if(sign == 1) {
                scanf("%d%d%d", &lx, &ly, &val);
                lx++, ly++;
                update(lx, ly, 1, n, 1, val);
            } else {
                scanf("%d%d%d%d", &lx, &ly, &rx, &ry);
                lx++, ly++, rx++, ry++;
                int ans = query(lx, rx, ly, ry, 1, n, 1);
                cout<<ans<<endl;
            }
        }
    }
}
时间: 2024-08-08 21:04:03

fafu 1100 线段树的相关文章

pku 2777(经典线段树染色问题)

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41202   Accepted: 12458 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.

HYSBZ 2243 染色 (线段树+树链剖分)

题意:中文题. 析:真是一个好题,但是我TLE了两天,就是因为输入那个询问数,我当作边数了,结果就是一个TLE... 大体思路,就是先进行用树链剖分,然后用线段树来维护,维护每个区间的不同数的个数,和每个数的值,在求的时候,在两个端点进行判断,是不是同一种,如果是就减去1,不是则不变. 而且发现一个问题,就是网上的代码所以输出的和我的不一样,但是都AC了,不知道是不是数据水.也不知道谁的对. 代码如下: #pragma comment(linker, "/STACK:1024000000,102

约会安排---hdu4553(线段树,麻烦的区间覆盖)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 算是poj3667的加强版,建立两颗线段树,一个是DS区间,另一个是NS区间.那么根据题意,如果是DS的请求,那么首先查找DS的区间,如果有满足的区间就更新DS区间,NS的区间不需要更新.如果是NS的请求,首先看DS区间是否有满足的区间,否则查找NS区间,如果有就同时更新DS区间和NS区间.那么可以归纳为,只要是NS的请求,就同时更新两颗线段树,否则只更新DS的线段树. 注意输出要从Outpu

spoj GSS线段树以及二维树状数组合集

T1 维护lmax 向左延伸的最大值,rmax同理,sum区间和,ans答案. 转移见operator + #include<bits/stdc++.h> #define mid (l+(r-l)/2) #define ls (rt<<1) #define rs (rt<<1|1) #define int long long using namespace std; const int N =(int)1e5+10; struct TREE { int lef,rig,

HDU 1540 Tunnel Warfare (线段树或set水过)

题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少. 析:首先可以用set水过,set用来记录每个被破坏的村庄,然后查找时,只要查找左右两个端点好. 用线段树的话,就维护三个值分别是左端点连续右端点连续,全连续的最长的区别,然后用线段树维护就好. 代码如下: set过: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #includ

HDU1542_Atlantis(扫描线/线段树+离散)

解题报告 题目传送门 题意: 求矩形并面积. 思路: 离散+线段树+扫描线. #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; struct Seg { int v; double h,lx,rx; friend bool operator < (Seg a,Seg b) { return a.h<b

BZOJ 1513 POI 2006 Tet-Tetris 3D 二维线段树

题目大意:三维俄罗斯方块,问最后摞了多高. 思路:二维线段树的裸题.但是要注意二维线段树不支持标记下穿.所以就不下传,每次更新答案的时候先看标记,然后用所有的跟标记比较大小之后返回. 具体看代码吧,不知道怎么说. CODE: #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define

线段树区间更新——POJ 2777

对应POJ题目:点击打开链接 Count Color Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, w

hdoj 4901 The Romantic Hero DP hdoj 4902 Nice boat 线段树

惨遭丽洁乱虐..这一场也是比得乱七八糟的,4902本是丽洁定义比较难的题,结果数据随机的,被许多暴力水过了..4905考察的是四边形不等式优化,但是这道题的dp方程实际上不满足该优化的条件..朴素的o(n^3)会超时,所以这题目前是没有正解了..我还写了个这题的贪心,强度挺高,可以对大概一半数据,错的误差也只有个位数,还揪出官方第五个数据..朴素dp和贪心跑这个数据都比官方数据多了1,也就证明这题不满足四边形不等式优化的条件.. http://acm.hdu.edu.cn/showproblem