C - Mobile phones(二维树状数组 单点更新 矩阵求和)

C - Mobile phones(二维树状数组)

POJ - 1195

题意:对一个 n n n*n nn的矩阵进行一些操作和查询,操作:单点修改。查询:求子矩阵元素和

思路:

​ 真没想到二维的树状数组是这样的。(真不知道二维线段树应该怎么维护,期待(☆▽☆)! )

构建二维树状数组之后我们可以求 i , j i,j i,j左上角矩阵的和 。求子矩阵可以转化为多个左上角矩阵元素和的加减。

二维树状数组的第二维(也就是行向量代表的节点吧)之间的关系,跟一维向量的 节点之间关系相同。

看博文:https://blog.csdn.net/chaiwenjun000/article/details/47973737

#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const ll MAXN=1050;
const ll MAX=1025;
ll bt[MAXN][MAXN];
ll lowbit(ll k)
{
    return k&-k;
}
ll getsum(ll de,ll k)//高度为de,的第k个元素左上角和
{
    ll ans=0;
    for(;de>0;de-=lowbit(de))
        for(int kk=k;kk>0;kk-=lowbit(kk))
            ans+=bt[de][kk];
    return ans;
}
void modify(ll de,ll k,ll val)
{
    for(;de<=MAX;de+=lowbit(de))
        for(int kk=k;kk<=MAX;kk+=lowbit(kk))
           bt[de][kk]+=val;;
}
ll calc(int l,int w,int r,int h)
{
    ll ans=getsum(h,r)-getsum(w-1,r)-getsum(h,l-1)+getsum(w-1,l-1);
    return ans;
}
int main(){
    ll n,cm;
    scanf("%lld %lld",&cm,&n);
    while(scanf("%lld",&cm),cm!=3)
    {
        if(cm==1)
        {
            ll x,y,val;
            scanf("%lld%lld%lld",&x,&y,&val);
            ++x,++y;
            modify(y,x,val);
        }
        else
        {
            ll l,r,w,h;
            scanf("%lld%lld%lld%lld",&l,&w,&r,&h);
            ++l,++w,++r,++h;
            printf("%lld\n",calc(l,w,r,h));
        }//
    }
}
全部评论

相关推荐

大方的大熊猫准备进厂:1.教育背景:你希望从事什么专业的工作你的主修课就是什么;成绩优秀是你应该做的,没什么可描述的,成绩不优秀也许人家在大学忙着创业呢?(成绩优秀不一定是好事,只能说明多元化的大学你上成了高中,没有真正上明白大学,反而体现了你死板,不爱社交,没有别的突出能力) 2.实践经历:你想表达的意思没有说清楚。你是说你会个性化服务,还是你有实习经历。如果没有带来,经济收益,表彰,更好的发展前景,那你还不如说说提升了自己哪些技能。你说有人给你送锦旗我都能明白你优秀,但是你说你会xxxx,你说这话谁信,证据呢。 3.入伍经历:你描述的就是你的工作职责或者你应该做的,并没有体现出来你把这个事情做好了,而且入伍经历并不能证明你能干好你要应聘的工作,不如只写经历其余所有内容都不写。 4.荣誉技能:重点突出一下,但不要过多描述,这些荣誉的含金量懂得都懂。 重点:你要应聘什么工作(具体岗位,实习生不具体),你的期望薪资
点赞 评论 收藏
分享
05-05 21:45
已编辑
广州大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务