二维树状数组+二维线段树


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 7;
inline ll read() {
    ll s = 0, w = 1;
    char ch = getchar();
    while (ch < 48 || ch > 57) {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57)
        s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
#define lowbit(x) (x&-x)
ll tree[maxn][maxn],tree2[maxn][maxn],tree3[maxn][maxn],tree4[maxn][maxn];
int n,m;
void add(int x,int y,ll val) {
    for(int i=x; i<=n; i+=lowbit(i))
        for(int j=y; j<=m; j+=lowbit(j)) {
            tree[i][j]+=val;
            tree2[i][j]+=x*val;
            tree3[i][j]+=y*val;
            tree4[i][j]+=x*y*val;
        }
}//对二维差分数组单点修改,logn*logm
void real_add(int x1,int y1,int x2,int y2,ll val) {
    add(x1,y1,val);
    add(x1,y2+1,-val);
    add(x2+1,y1,-val);
    add(x2+1,y2+1,val);
}//对原数组区间修改
ll ask(int x,int y) {
    ll res=0,res2=0,res3=0,res4=0;
    for(int i=x; i; i-=lowbit(i))
        for(int j=y; j; j-=lowbit(j)) {
            res+=tree[i][j];
            res2+=tree2[i][j];
            res3+=tree3[i][j];
            res4+=tree4[i][j];
        }
    return (x+1)*(y+1)*res-(y+1)*res2-(x+1)*res3+res4;
}//求原数组的前缀和,logn*logm
ll real_ask(int x1,int y1,int x2,int y2) {
    return ask(x2,y2)-ask(x2,y1-1)-ask(x1-1,y2)+ask(x1-1,y1-1);
}//区间求和
ll sum(int x,int y) {
    ll res=0;
    for(int i=x; i; i-=lowbit(i))
        for(int j=y; j; j-=lowbit(j))
            res+=tree[i][j];
    return res;
}//求gad[x][y]
int a,b,gad[maxn][maxn];
int main() {
    int t=read();
    while(t--) {
        memset(tree,0,sizeof tree);
        memset(tree2,0,sizeof tree2);
        memset(tree3,0,sizeof tree3);
        memset(tree4,0,sizeof tree4);
        n = read(), m = read();
        for(int i=1,val; i<=n; ++i)
            for(int j=1; j<=m; ++j) {
                gad[i][j]=read();
                real_add(i,j,i,j,gad[i][j]);
                //add(i,j,gad[i][j]-gad[i][j-1]-gad[i-1][j]+gad[i-1][j-1]);//这样写也行 
            }
        cout<<sum(n,m)<<endl;
        //cout<<real_ask(2,3,2,3)<<endl;
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
inline ll read() {
    ll s = 0, w = 1;
    char ch = getchar();
    while (ch < 48 || ch > 57) {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57)
        s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
ll sum[1025 << 2][1025 << 2], n, m,lazy[1025<<2][1025<<2];
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
void Subbuild(int l, int r, int rt, int t) {
    lazy[t][rt]=0;
    if (l == r) {
        int val = read();
        sum[t][rt] = val;
        return;
    }
    int mid = (l + r) >> 1;
    Subbuild(lson, t);
    Subbuild(rson, t);
    sum[t][rt] = sum[t][rt << 1] + sum[t][rt << 1 | 1];
}
void updown(int l,int r,int rt,int t) {
    if(l==r) {
        sum[t][rt]=sum[t<<1][rt]+sum[t<<1|1][rt];
        return;
    }
    int mid=l+r>>1;
    if(1<=mid) updown(lson,t);
    if(m>mid) updown(rson,t);
    sum[t][rt]=sum[t][rt<<1]+sum[t][rt<<1|1];
}
void build(int l, int r, int rt) {
    if (l == r) {
        Subbuild(1, m, 1, rt);
        return;
    }
    int mid = (l + r) >> 1;
    build(lson);
    build(rson);
    updown(1,m,1,rt);
}
void push_down(int &t,int &rt,int m) {
    if(lazy[t][rt]) {
        lazy[t][rt<<1]+=lazy[t][rt];
        lazy[t][rt<<1|1]+=lazy[t][rt];
        sum[t][rt<<1]+=(m-(m>>1))*lazy[t][rt];
        sum[t][rt<<1|1]+=(m>>1)*lazy[t][rt];
        lazy[t][rt]=0;
    }
}
void subupdate(int a,int b,ll val,int l,int r,int rt,int t) {
    if(a<=l&&b>=r) {
        sum[t][rt]+=(r-l+1)*val;
        lazy[t][rt]+=val;
        return;
    }
    push_down(t,rt,r-l+1);
    int mid=l+r>>1;
    if(a<=mid) subupdate(a,b,val,lson,t);
    if(b>mid) subupdate(a,b,val,rson,t);
    sum[t][rt]=sum[t][rt<<1]+sum[t][rt<<1|1];
}
void update(int x1,int x2,int y1,int y2,ll val,int l,int r,int rt) {
    subupdate(y1,y2,val,1,m,1,rt);
    if(l!=r) {
        int mid=l+r>>1;
        if(x1<=mid)    update(x1,x2,y1,y2,val,lson);
        if(x2>mid) update(x1,x2,y1,y2,val,rson);
    }
}
ll subquery(int a,int b,int l,int r,int rt,int t) {
    if(a<=l&&b>=r)    return sum[t][rt];
    push_down(t,rt,r-l+1);
    int mid=l+r>>1;
    ll ans=0;
    if(a<=mid) ans+=subquery(a,b,lson,t);
    if(b>mid)    ans+=subquery(a,b,rson,t);
    return ans;
}
ll query(int x,int xx,int y,int yy,int l,int r,int rt) {
    if(x<=l&&xx>=r)    return subquery(y,yy,1,m,1,rt);
    int mid=l+r>>1;
    ll ans=0;
    if(x<=mid)    ans+=query(x,xx,y,yy,lson);
    if(xx>mid)    ans+=query(x,xx,y,yy,rson);
    return ans;
}
int main() {
    int t=read();
    while(t--) {
        n = read(), m = read();
        memset(lazy,0,sizeof lazy);
        build(1, n, 1);
        cout<<query(1,n,1,m,1,n,1)<<endl;
    }
    return 0;
}
全部评论

相关推荐

行云流水1971:这份实习简历的优化建议: 结构清晰化:拆分 “校园经历”“实习经历” 板块(当前内容混杂),按 “实习→校园→技能” 逻辑排版,求职意向明确为具体岗位(如 “市场 / 运营实习生”)。 经历具象化:现有描述偏流程,需补充 “动作 + 数据”,比如校园活动 “负责宣传” 可加 “运营公众号发布 5 篇推文,阅读量超 2000+,带动 300 + 人参与”;实习内容补充 “协助完成 XX 任务,效率提升 X%”。 岗位匹配度:锚定目标岗位能力,比如申请运营岗,突出 “内容编辑、活动执行” 相关动作;申请市场岗,强化 “资源对接、数据统计” 细节。 信息精简:删减冗余表述(如重复的 “负责”),用短句分点,比如 “策划校园招聘会:联系 10 + 企业,组织 200 + 学生参与,到场率达 85%”。 技能落地:将 “Office、PS” 绑定经历,比如 “用 Excel 整理活动数据,输出 3 份分析表;用 PS 设计 2 张活动海报”,避免技能单独罗列。 优化后需强化 “经历 - 能力 - 岗位需求” 的关联,让实习 / 校园经历的价值更直观。 若需要进一步优化服务,私信
实习,投递多份简历没人回...
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

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