uva 11992 线段树对矩阵进行更新查询
来源:互联网 发布:中国博士与英国知乎 编辑:程序博客网 时间:2024/05/10 17:54
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3143
把矩阵变成一行,然后计算位置,lrj给了线段树数组做法 但是我做的线段树空间过大,直接爆掉,所以换方法了
主要还是测试自己的线段树区间更新的模板
各种RE+WA之后AC,,,,,
做的时候出现的几个错误:
1、行和列弄错
2、build初始化的时候,mmin mmax 都初始化为0才对
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
-
- #define lson(i) l , mid , (i)*2
- #define rson(i) mid + 1 , r , ((i)*2 +1)
- #define ll rt*2
- #define rr (rt*2+1)
-
- const int INFMIN = 0xffffffff;
- const int INFMAX = 1000000009;
- const int MAXN = 30001000;
- struct Node{
- int l,r;
- int mmax,mmin,sum,add,s;
- };
- Node nodes[MAXN];
-
- int mmax,mmin,sum;
- void PushUp(int rt)
- {
- nodes[rt].mmax = max(nodes[ll].mmax,nodes[rr].mmax);
- nodes[rt].mmin = min(nodes[ll].mmin,nodes[rr].mmin);
- nodes[rt].sum = nodes[ll].sum + nodes[rr].sum;
- }
- void PushDown(int rt)
- {
-
- if(nodes[rt].add)
- {
- nodes[ll].add += nodes[rt].add;
- nodes[ll].mmin += nodes[rt].add;
- nodes[ll].mmax += nodes[rt].add;
- nodes[rr].add += nodes[rt].add;
- nodes[rr].mmin += nodes[rt].add;
- nodes[rr].mmax += nodes[rt].add;
-
- nodes[ll].sum += nodes[rt].add*(nodes[ll].r-nodes[ll].l+1);
- nodes[rr].sum += nodes[rt].add*(nodes[rr].r-nodes[rr].l+1);
- nodes[rt].add = 0;
- }
-
- if(nodes[rt].s)
- {
- nodes[ll].s = nodes[rr].s=nodes[rt].s;
- nodes[ll].mmin = nodes[ll].mmax = nodes[rr].mmax = nodes[rr].mmin = nodes[rt].mmax;
- nodes[ll].sum = nodes[rt].mmin*(nodes[ll].r-nodes[ll].l+1);
- nodes[rr].sum = nodes[rt].mmin*(nodes[rr].r-nodes[rr].l+1);
- nodes[ll].add = nodes[rr].add = 0;
- nodes[rt].s=0;
- }
- }
- void Build(int l,int r,int rt)
- {
- nodes[rt].l=l;
- nodes[rt].r=r;
- nodes[rt].add =0;
- nodes[rt].s=0;
- nodes[rt].sum =0;
- nodes[rt].mmin=0;
- nodes[rt].mmax=0;
- if(l == r)
- {
-
- nodes[rt].mmin = nodes[rt].mmax = nodes[rt].sum =0;
- return ;
- }
- int mid = (nodes[rt].l+nodes[rt].r)/2;
- Build(lson(rt));
- Build(rson(rt));
-
- }
-
- void Update(int l,int r,int add,int rt,int flag)
- {
-
-
- if(l<=nodes[rt].l && nodes[rt].r<=r)
- {
- if(flag == 1)
- {
- nodes[rt].mmax += add;
- nodes[rt].mmin += add;
- nodes[rt].add += add;
- nodes[rt].sum += add*(nodes[rt].r-nodes[rt].l+1);
-
- }
- else
- {
- nodes[rt].mmax = add;
- nodes[rt].mmin = add;
- nodes[rt].add=0;
- nodes[rt].s=1;
- nodes[rt].sum = add*(nodes[rt].r-nodes[rt].l+1);
- }
- return;
- }
- PushDown(rt);
- int mid = (nodes[rt].l+nodes[rt].r)/2;
- if(l<=mid)Update(l,r,add,ll,flag);
- if(r>mid)Update(l,r,add,rr,flag);
- PushUp(rt);
- }
- void Query(int l,int r,int rt)
- {
-
-
-
- if(l<=nodes[rt].l && nodes[rt].r<=r)
- {
- mmin = min(mmin,nodes[rt].mmin);
- mmax = max(mmax,nodes[rt].mmax);
- sum += nodes[rt].sum;
- return ;
- }
- PushDown(rt);
- int mid = (nodes[rt].l+nodes[rt].r)/2;
- if(l<=mid)Query(l,r,ll);
- if(r>mid)Query(l,r,rr);
- PushUp(rt);
- }
- void clr()
- {
- sum =0;
- mmin=INFMAX;
- mmax=INFMIN;
- }
-
- int main()
- {
-
- int r,c,m,v,flag,x1,y1,x2,y2;
-
- while(scanf("%d%d%d",&r,&c,&m)!=EOF)
- {
- Build(1,r*c,1);
- while(m--)
- {
- scanf("%d%d%d%d%d",&flag,&x1,&y1,&x2,&y2);
- if(flag<3)
- {
- scanf("%d",&v);
- for(int i=x1;i<=x2;i++)
- {
-
-
-
- Update(y1+(i-1)*c,y2+(i-1)*c,v,1,flag);
- }
- }
- else
- {
- int anssum=0,ansmin=INFMAX,ansmax=INFMIN;
- for(int i=x1;i<=x2;i++)
- {
- clr();
- Query(y1+(i-1)*c,y2+(i-1)*c,1);
-
-
-
- anssum+=sum;
- ansmax=max(ansmax,mmax);
- ansmin=min(ansmin,mmin);
- }
- printf("%d %d %d\n",anssum,ansmin,ansmax);
- }
- }
- }
-
- return 0;
- }
0 0