二维线段树模板,建树,维护最大最小值
#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;
}
不疯魔不成活