二维线段树模板,建树,维护最大最小值

#include<bits/stdc++.h>
using namespace std;
const int N=805;
#define son(x) (rt*4-2+x)
#define ll long long
struct node{
    int mn;
    int mx;
    void reset(){
       mx=INT_MIN;
        mn=INT_MAX;
    }
}tree[(N<<2)*(N<<2)];

void build(int rt, int xl, int xr, int yl, int yr){
    if(xl>xr || yl>yr) return;
    tree[rt].reset();
    if(xl==xr&&yl==yr)
        return;
    int midx=(xl+xr)>>1, midy=(yl+yr)>>1;
    build(son(0), xl, midx, yl, midy);
    build(son(1), xl, midx, midy+1, yr);
    build(son(2), midx+1, xr, yl, midy);
    build(son(3), midx+1, xr, midy+1, yr);
}
//push_up完全可以放在跟新里面 写起来更简洁
void push_up(int rt, int xl, int xr, int yl, int yr){
    node& now=tree[rt];
    now.reset();
   now.mx=max(now.mx, tree[son(0)].mx);
    now.mn=min(now.mn, tree[son(0)].mn);
    if(yl<yr){
       now.mx=max(now.mx, tree[son(1)].mx);
        now.mn=min(now.mn, tree[son(1)].mn);
    }
    if(xl<xr){
       now.mx=max(now.mx, tree[son(2)].mx);
        now.mn=min(now.mn, tree[son(2)].mn);
    }
    if(xl<xr && yl<yr){
       now.mx=max(now.mx, tree[son(3)].mx);
        now.mn=min(now.mn, tree[son(3)].mn);
    }
}

//point update
void upd(int rt, int xl, int xr, int yl, int yr, int x, int y, int val){
    if(xl>xr || yl>yr) return;

    node& now=tree[rt];
    if(xl==xr&&xl==x && yl==yr&&yl==y){
        now.mx=val;
        now.mn=val;
        return;
    }
    int midx=(xl+xr)>>1, midy=(yl+yr)>>1;

    if(x<=midx && y<=midy){
        upd(son(0), xl, midx, yl, midy, x, y, val);
    }
    else if(x<=midx && y>midy){
        upd(son(1), xl, midx, midy+1, yr, x, y, val);
    }
    else if(x>midx && y<=midy){
        upd(son(2), midx+1, xr, yl, midy, x, y, val);
    }
    else{
        upd(son(3), midx+1, xr, midy+1, yr, x, y, val);
    }

    push_up(rt, xl, xr, yl, yr);
}
//interval query
node query(int rt, int xl, int xr, int yl, int yr, int qxl, int qxr, int qyl, int qyr){
    node tmp; tmp.reset();
    if(xl>xr || yl>yr) return tmp;
    if(xl>qxr || qxl>xr || yl>qyr || qyl>yr) return tmp;

    if(qxl<=xl && xr<=qxr && qyl<=yl && yr<=qyr){
        return tree[rt];
    }
    int midx=(xl+xr)>>1, midy=(yl+yr)>>1;
    node ret; ret.reset();
    if(qxl<=midx && qyl<=midy){
        tmp=query(son(0), xl, midx, yl, midy, qxl, qxr, qyl, qyr);
        ret.mx=max(ret.mx, tmp.mx);
        ret.mn=min(ret.mn, tmp.mn);
    }
    if(qxl<=midx && qyr>midy){
        tmp=query(son(1), xl, midx, midy+1, yr, qxl, qxr, qyl, qyr);
        ret.mx=max(ret.mx, tmp.mx);
        ret.mn=min(ret.mn, tmp.mn);
    }
    if(qxr>midx && qyl<=midy){
        tmp=query(son(2), midx+1, xr, yl, midy, qxl, qxr, qyl, qyr);
        ret.mx=max(ret.mx, tmp.mx);
        ret.mn=min(ret.mn, tmp.mn);
    }
    if(qxr>midx && qyr>midy){
        tmp=query(son(3), midx+1, xr, midy+1, yr, qxl, qxr, qyl, qyr);
        ret.mx=max(ret.mx, tmp.mx);
        ret.mn=min(ret.mn, tmp.mn);
    }

    return ret;
}

int main(){
    int n,m,a,b;
    ll g,x,y,z;
    scanf("%d%d%d%d",&n,&m,&a,&b);
    scanf("%lld%lld%lld%lld",&g,&x,&y,&z);
     build(1, 1, n, 1, m);
     int temp;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
        if(i==1&&j==1){temp=g;}
        else temp=(g*x%z+y)%z;
        upd(1, 1, n, 1, m, i, j, temp);
        g=temp;
       }
    }

    ll sum=0;
    node ans;
    for(int i=1;i<=n-a+1;i++){
         for(int j=1;j<=m-b+1;j++){
       //qxl,qxr依然是纵向,对应i(对应n)
       int qxl=i, qxr=i+a-1;
       int qyl=j, qyr=j+b-1;
        ans=query(1, 1, n, 1, m, qxl, qxr, qyl, qyr);
        sum+=ans.mn;
    }
    }

    printf("%lld\n",sum);
    return 0;
}
全部评论

相关推荐

10-17 12:16
同济大学 Java
7182oat:快快放弃了然后发给我,然后让我也泡他七天最后再拒掉,狠狠羞辱他一把😋
点赞 评论 收藏
分享
10-28 15:45
门头沟学院 C++
西南山:海康威视之前不是大规模裁员吗
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务