• 【树状数组二维区间加+区间查询模板】bzoj3132


    新知识,其实和之前讲过的一维差不多,只要维护四个数组就行了,不过还是参考了别人的代码,还是要好好练练才行

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 2050
    using namespace std;
    int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],d[maxn][maxn];
    int n,m;
    int lowbit(int x){return(x&-x);}
    void update(int x,int y,int v,int g[][maxn])
    {
      for (int i=x;i<=n;i+=lowbit(i)) for (int j=y;j<=m;j+=lowbit(j)) 
      g[i][j]+=v;
    }
    int query(int x,int y,int g[][maxn])
    {
      int sum=0;
      for (int i=x;i>0;i-=lowbit(i))
      for (int j=y;j>0;j-=lowbit(j))
      sum+=g[i][j];
      return sum;
    }
    int calc(int x,int y)
    {
      int sum=query(x,y,a)+query(x,y,b)*x+query(x,y,c)*y+query(x,y,d)*x*y;
      return sum;
    }
    void add(int x,int y,int v)
    {
      if (!x||!y) return;
      update(x,y,x*y*v,a);
      update(x,y,y*-v,b); update(1,y,y*v,b);
      update(x,y,x*-v,c); update(x,1,x*v,c);
      update(x,y,v,d);update(1,1,v,d);
      update(x,1,-v,d);update(1,y,-v,d);
    //这里是重点,在访问到当前的时候,会加上一个值,过了边界的时候再减去这个值 }
    int main() { char ch; scanf("%c %d%d",&ch,&n,&m); int x,y,xx,yy,val; while (scanf(" %c ",&ch)!=EOF) { if (ch=='L') { scanf("%d%d%d%d%d",&x,&y,&xx,&yy,&val); add(x-1,y-1,val);add(xx,yy,val);add(xx,y-1,-val);add(x-1,yy,-val); } else { scanf("%d%d%d%d",&x,&y,&xx,&yy);x--;y--; int ans=calc(xx,yy)-calc(xx,y)-calc(x,yy)+calc(x,y); printf("%d ",ans); } } return 0; }
  • 相关阅读:
    FCLK、HCLK、PCLK
    CPU位数、地址线位数、数据线位数、通用寄存器位数!
    Java实现线程的三种方式和区别
    数据结构之二叉树
    List&Map&Set的操作和遍历
    从源码看Java集合之ArrayList
    Java设计模式概述
    Java实现单例的5种方式
    Java序列化
    水仙花数
  • 原文地址:https://www.cnblogs.com/2014nhc/p/7398164.html
Copyright © 2020-2023  润新知