zoukankan      html  css  js  c++  java
  • Codeforces 390E Inna and Large Sweet Matrix 树状数组改段求段

    题目链接:点击打开链接

    题意:给定n*m的二维平面 w个操作

    int mp[n][m] = { 0 };

    1、0 (x1,y1) (x2,y2) value

    for i : x1 to x2

    for j : y1 to y2 

    mp[i][j] += value;

    2、1 (x1, y1) (x2 y2)

    ans1 = 纵坐标在 y1,y2间的总数

    ans2 = 横坐标不在x1,x2间的总数

    puts(ans1-ans2);

    more format:

    for i : 1 to n

    for j : y1 to y2

    ans1 += mp[i][j]


    由于n最大是4e6, 所以用树状数组改段求段取代线段树



    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <iostream>
    template <class T>
    inline bool rd(T &ret) {
    	char c; int sgn;
    	if (c = getchar(), c == EOF) return 0;
    	while (c != '-' && (c<'0' || c>'9')) c = getchar();
    	sgn = (c == '-') ? -1 : 1;
    	ret = (c == '-') ? 0 : (c - '0');
    	while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
    	ret *= sgn;
    	return 1;
    }
    template <class T>
    inline void pt(T x) {
    	if (x <0) {
    		putchar('-');
    		x = -x;
    	}
    	if (x>9) pt(x / 10);
    	putchar(x % 10 + '0');
    }
    using namespace std;
    typedef long long ll;
    const int N = 4e6 + 100;
    template<class T>
    struct Tree{
    	T c[2][N];
    	int maxn;
    	void init(int x){
    		maxn = x+10; memset(c, 0, sizeof c);
    	}
    	inline int lowbit(int x){ return x&-x; }
    	T sum(T *b, int x){
    		T ans = 0;
    		if (x == 0)ans = b[0];
    		while (x)ans += b[x], x -= lowbit(x);
    		return ans;
    	}
    	void change(T *b, int x, T value){
    		if (x == 0)b[x] += value, x++;
    		while (x <= maxn)b[x] += value, x += lowbit(x);
    	}
    	T get_pre(int r){
    		return sum(c[0], r) * r + sum(c[1], r);
    	}
    	void add(int l, int r, T value){
    		change(c[0], l, value);
    		change(c[0], r + 1, -value);
    		change(c[1], l, value * (-l + 1));
    		change(c[1], r + 1, value * r);
    	}
    	T get(int l, int r){
    		return get_pre(r) - get_pre(l - 1);
    	}
    };
    Tree<ll> x, y;
    int main(){
    	int n, m, w;
    	rd(n); rd(m); rd(w);
    	x.init(n); y.init(m);
    	ll all = 0;
    	while (w--){
    		int op, x1, x2, y1, y2; ll value;
    		rd(op); rd(x1); rd(y1); rd(x2); rd(y2);
    		if (op == 0)
    		{
    			rd(value);
    			all += value * (x2 - x1 + 1) * (y2 - y1 + 1);
    			x.add(x1, x2, value * (y2 - y1 + 1));
    			y.add(y1, y2, value * (x2 - x1 + 1));
    		}
    		else
    		{
    			pt(y.get(1, y2) - y.get(1, y1 - 1) - (all - x.get(1, x2) + x.get(1, x1 - 1))); puts("");
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    [OI学习笔记]排列组合&二项式定理
    [OI学习笔记]拓补排序
    [OI学习笔记]DAG最短路的四种算法整理-floyd,Dijkstra,Bellman-Ford,SPFA
    [OI学习笔记]从蒟蒻的角度理解动态规划(DP)——从暴力搜索到动态规划
    [OI学习笔记]最小生成树之Kruskal算法
    [OI学习笔记]最小生成树之Prim算法
    [OI学习笔记]图的存储与遍历-邻接矩阵&邻接表
    将数组中第n个元素,放到第m个元素后面
    Unity3D中播放序列帧动画
    UVA1589 Xiangqi
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6781682.html
Copyright © 2011-2022 走看看