UVA11992不错的线段树段更新
生活随笔
收集整理的這篇文章主要介紹了
UVA11992不错的线段树段更新
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給你一個矩陣,最大20*50000的,然后有三個操作
1 x1 y1 x2 y2 v ?把子矩陣的值全部都加上v
2 x1 y1 x2 y2 v ?把子矩陣的值全部都變成v
2 x1 y1 x2 y2 ?查詢子矩陣的和,最大值,最小值
思路: ?
? ? ? 首先我們觀察,矩陣的行最多20行,那么我們就可以把每一行都建一顆線段樹,這樣就變成了一個一維的線段樹段更新問題了,然后還有一個問題,就是操作1,和操作2,這兩個操作放在一起感覺有些棘手,看白書上的思路不懂,沒辦法自己想了好久,想到了一個比較笨的思路,但感覺應該容易理解點,最近天天寫軟件,沒怎么刷題,今天1a了感覺很開心啊,廢話補多少回來說1,2的問題,我是這樣想的,主要就是處理好延遲跟新的那個地方,總結就是一句話,在關系(延遲更新的是更改還是增加)傳遞的時候遇到“更改”那么下面的所有經過的點的屬性都變成更改,其他情況直接由父節點傳遞過來,這么說可能不懂,我再換個角度說,對于某一個點,無論之前做過什么操作,如果現在是面臨"更改"(不是增加)那么之前的操作全都無效,直接更改,如果面臨的是增加操作,那么如果上一步是更改操作的話,那么從這一步起,之后就變成更改操作,具體細節可以看下面代碼,自己想的思路可能不是很正宗,有點亂。
? ? ?
#include<stdio.h>
#include<string.h>
#define R 20 + 2
#define C 200000 + 100
#define lson l ,mid ,t << 1
#define rson mid + 1 ,r ,t << 1 | 1
typedef struct
{
? ? int sum ,min ,max;
}NODE;
int Sum[R][C] ,Max[R][C] ,Min[R][C];
int mark[R][C] ,mks[R][C];
int NOWI;
int maxx(int x ,int y)
{
? ? return x > y ? x : y;
}
int minn(int x ,int y)
{
? ? return x < y ? x : y;
}
void Pushup(int t)
{
? ? Sum[NOWI][t] = Sum[NOWI][t << 1] + Sum[NOWI][t << 1 | 1];
? ? Max[NOWI][t] = maxx(Max[NOWI][t << 1] ,Max[NOWI][t << 1 | 1]);
? ? Min[NOWI][t] = minn(Min[NOWI][t << 1] ,Min[NOWI][t << 1 | 1]);
? ? return ;
}
void Pushdown(int l ,int r ,int t)
{
? ? if(mark[NOWI][t])
? ? {
? ? ? ? int ll = r - l + 1;
? ? ? ? if(mks[NOWI][t] == 1)
? ? ? ? {
? ? ? ? ? ? mark[NOWI][t<<1] = mark[NOWI][t<<1|1] = mark[NOWI][t];
? ? ? ? ? ? mks[NOWI][t<<1] = mks[NOWI][t<<1|1] = mks[NOWI][t];
? ? ? ? ? ? Sum[NOWI][t<<1] = (ll - ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Sum[NOWI][t<<1|1] = (ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Max[NOWI][t<<1] = Max[NOWI][t<<1|1] = mark[NOWI][t];
? ? ? ? ? ? Min[NOWI][t<<1] = Min[NOWI][t<<1|1] = mark[NOWI][t];
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? mark[NOWI][t<<1] += mark[NOWI][t];
? ? ? ? ? ? mark[NOWI][t<<1|1] += mark[NOWI][t];
? ? ? ? ? ? if(mks[NOWI][t<<1] != 1) mks[NOWI][t<<1] = 2;
? ? ? ? ? ? if(mks[NOWI][t<<1|1] != 1) mks[NOWI][t<<1|1] = 2;
? ? ? ? ? ? Sum[NOWI][t<<1] += (ll - ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Sum[NOWI][t<<1|1] += (ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Max[NOWI][t<<1] += mark[NOWI][t];
? ? ? ? ? ? Max[NOWI][t<<1|1] += mark[NOWI][t];
? ? ? ? ? ? Min[NOWI][t<<1] += mark[NOWI][t];
? ? ? ? ? ? Min[NOWI][t<<1|1] += mark[NOWI][t];
? ? ? ? }
? ? ? ? mark[NOWI][t] = mks[NOWI][t] = 0;
? ? }
}
void BuidTree()
{
? ? memset(mark ,0 ,sizeof(mark));
? ? memset(mks ,0 ,sizeof(mks));
? ? memset(Sum ,0 ,sizeof(Sum));
? ? memset(Max ,0 ,sizeof(Max));
? ? memset(Min ,0 ,sizeof(Min));
}
void Update(int l ,int r ,int t ,int a ,int b ,int c ,int mk)
{
? ? if(a <= l && b >= r)
? ? {
? ? ? ? if(mk == 1)
? ? ? ? {
? ? ? ? ? ? Sum[NOWI][t] = (r - l + 1) * c;
? ? ? ? ? ? Max[NOWI][t] = Min[NOWI][t] = c;
? ? ? ? ? ? mark[NOWI][t] = c;
? ? ? ? ? ? mks[NOWI][t] = 1;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? Sum[NOWI][t] += (r - l + 1) * c;
? ? ? ? ? ? Max[NOWI][t] += c;
? ? ? ? ? ? Min[NOWI][t] += c;
? ? ? ? ? ? mark[NOWI][t] += c;
? ? ? ? ? ? if(mks[NOWI][t] != 1) mks[NOWI][t] = 2;
? ? ? ? }
? ? ? ? return;
? ? }
? ? Pushdown(l ,r ,t);
? ? int mid = (l + r) >> 1;
? ? if(a <= mid) Update(lson ,a ,b ,c ,mk);
? ? if(b > mid) Update(rson ,a ,b ,c ,mk);
? ? Pushup(t);
? ? return;
}
NODE Query(int l ,int r ,int t ,int a ,int b)
{
? ? if(a <= l && b >= r)
? ? {
? ? ? ? NODE Ans;
? ? ? ? Ans.sum = Sum[NOWI][t];
? ? ? ? Ans.max = Max[NOWI][t];
? ? ? ? Ans.min = Min[NOWI][t];
? ? ? ? return Ans;
? ? }
? ? Pushdown(l ,r ,t);
? ? int tsum = 0 ,tmin = 1000000000 ,tmax = -1000000000;
? ? int mid = (l + r) >> 1;
? ? if(a <= mid)
? ? {
? ? ? ? NODE now = Query(lson ,a ,b);
? ? ? ? tsum += now.sum;
? ? ? ? if(tmin > now.min) tmin = now.min;
? ? ? ? if(tmax < now.max) tmax = now.max;
? ? }
? ? if(b > mid)
? ? {
? ? ? ? NODE now = Query(rson ,a ,b);
? ? ? ? tsum += now.sum;
? ? ? ? if(tmin > now.min) tmin = now.min;
? ? ? ? if(tmax < now.max) tmax = now.max;
? ? }
? ? NODE Ans;
? ? Ans.sum = tsum ,Ans.min = tmin ,Ans.max = tmax;
? ? return Ans;
}
int main ()
{
? ? int x1 ,y1 ,x2 ,y2 ,key ,v ,r ,c ,m ,i;
? ? while(~scanf("%d %d %d" ,&r ,&c ,&m))
? ? {
? ? ? ? BuidTree();
? ? ? ? while(m--)
? ? ? ? {
? ? ? ? ? ? scanf("%d" ,&key);
? ? ? ? ? ? if(key == 1)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? scanf("%d %d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2 ,&v);
? ? ? ? ? ? ? ? for(i = x1 ;i <= x2 ;i ++)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? NOWI = i;
? ? ? ? ? ? ? ? ? ? Update(1 ,c ,1 ,y1 ,y2 ,v ,2);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else if(key == 2)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? scanf("%d %d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2 ,&v);
? ? ? ? ? ? ? ? for(i = x1 ;i <= x2 ;i ++)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? NOWI = i;
? ? ? ? ? ? ? ? ? ? Update(1 ,c ,1 ,y1 ,y2 ,v ,1);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ?scanf("%d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2);
? ? ? ? ? ? ? ?NODE Ans ,NOW;
? ? ? ? ? ? ? ?for(i = x1 ;i <= x2 ;i ++)
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?NOWI = i;
? ? ? ? ? ? ? ? ? ?NOW = Query(1 ,c ,1 ,y1 ,y2);
? ? ? ? ? ? ? ? ? ?if(i == x1) Ans = NOW;
? ? ? ? ? ? ? ? ? ?else
? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ?Ans.sum += NOW.sum;
? ? ? ? ? ? ? ? ? ? ? ?Ans.max = maxx(Ans.max ,NOW.max);
? ? ? ? ? ? ? ? ? ? ? ?Ans.min = minn(Ans.min ,NOW.min);
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?printf("%d %d %d\n" ,Ans.sum ,Ans.min ,Ans.max);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
/*
4 4 8
1 1 2 4 4 5
3 2 1 4 4
1 1 1 3 4 2
3 1 2 4 4
3 1 1 3 4
2 2 1 4 4 2
3 1 2 4 4
1 1 1 4 3 3
45 0 5
78 5 7
69 2 7
39 2 7
*/
? ? ? 給你一個矩陣,最大20*50000的,然后有三個操作
1 x1 y1 x2 y2 v ?把子矩陣的值全部都加上v
2 x1 y1 x2 y2 v ?把子矩陣的值全部都變成v
2 x1 y1 x2 y2 ?查詢子矩陣的和,最大值,最小值
思路: ?
? ? ? 首先我們觀察,矩陣的行最多20行,那么我們就可以把每一行都建一顆線段樹,這樣就變成了一個一維的線段樹段更新問題了,然后還有一個問題,就是操作1,和操作2,這兩個操作放在一起感覺有些棘手,看白書上的思路不懂,沒辦法自己想了好久,想到了一個比較笨的思路,但感覺應該容易理解點,最近天天寫軟件,沒怎么刷題,今天1a了感覺很開心啊,廢話補多少回來說1,2的問題,我是這樣想的,主要就是處理好延遲跟新的那個地方,總結就是一句話,在關系(延遲更新的是更改還是增加)傳遞的時候遇到“更改”那么下面的所有經過的點的屬性都變成更改,其他情況直接由父節點傳遞過來,這么說可能不懂,我再換個角度說,對于某一個點,無論之前做過什么操作,如果現在是面臨"更改"(不是增加)那么之前的操作全都無效,直接更改,如果面臨的是增加操作,那么如果上一步是更改操作的話,那么從這一步起,之后就變成更改操作,具體細節可以看下面代碼,自己想的思路可能不是很正宗,有點亂。
? ? ?
#include<stdio.h>
#include<string.h>
#define R 20 + 2
#define C 200000 + 100
#define lson l ,mid ,t << 1
#define rson mid + 1 ,r ,t << 1 | 1
typedef struct
{
? ? int sum ,min ,max;
}NODE;
int Sum[R][C] ,Max[R][C] ,Min[R][C];
int mark[R][C] ,mks[R][C];
int NOWI;
int maxx(int x ,int y)
{
? ? return x > y ? x : y;
}
int minn(int x ,int y)
{
? ? return x < y ? x : y;
}
void Pushup(int t)
{
? ? Sum[NOWI][t] = Sum[NOWI][t << 1] + Sum[NOWI][t << 1 | 1];
? ? Max[NOWI][t] = maxx(Max[NOWI][t << 1] ,Max[NOWI][t << 1 | 1]);
? ? Min[NOWI][t] = minn(Min[NOWI][t << 1] ,Min[NOWI][t << 1 | 1]);
? ? return ;
}
void Pushdown(int l ,int r ,int t)
{
? ? if(mark[NOWI][t])
? ? {
? ? ? ? int ll = r - l + 1;
? ? ? ? if(mks[NOWI][t] == 1)
? ? ? ? {
? ? ? ? ? ? mark[NOWI][t<<1] = mark[NOWI][t<<1|1] = mark[NOWI][t];
? ? ? ? ? ? mks[NOWI][t<<1] = mks[NOWI][t<<1|1] = mks[NOWI][t];
? ? ? ? ? ? Sum[NOWI][t<<1] = (ll - ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Sum[NOWI][t<<1|1] = (ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Max[NOWI][t<<1] = Max[NOWI][t<<1|1] = mark[NOWI][t];
? ? ? ? ? ? Min[NOWI][t<<1] = Min[NOWI][t<<1|1] = mark[NOWI][t];
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? mark[NOWI][t<<1] += mark[NOWI][t];
? ? ? ? ? ? mark[NOWI][t<<1|1] += mark[NOWI][t];
? ? ? ? ? ? if(mks[NOWI][t<<1] != 1) mks[NOWI][t<<1] = 2;
? ? ? ? ? ? if(mks[NOWI][t<<1|1] != 1) mks[NOWI][t<<1|1] = 2;
? ? ? ? ? ? Sum[NOWI][t<<1] += (ll - ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Sum[NOWI][t<<1|1] += (ll / 2) * mark[NOWI][t];
? ? ? ? ? ? Max[NOWI][t<<1] += mark[NOWI][t];
? ? ? ? ? ? Max[NOWI][t<<1|1] += mark[NOWI][t];
? ? ? ? ? ? Min[NOWI][t<<1] += mark[NOWI][t];
? ? ? ? ? ? Min[NOWI][t<<1|1] += mark[NOWI][t];
? ? ? ? }
? ? ? ? mark[NOWI][t] = mks[NOWI][t] = 0;
? ? }
}
void BuidTree()
{
? ? memset(mark ,0 ,sizeof(mark));
? ? memset(mks ,0 ,sizeof(mks));
? ? memset(Sum ,0 ,sizeof(Sum));
? ? memset(Max ,0 ,sizeof(Max));
? ? memset(Min ,0 ,sizeof(Min));
}
void Update(int l ,int r ,int t ,int a ,int b ,int c ,int mk)
{
? ? if(a <= l && b >= r)
? ? {
? ? ? ? if(mk == 1)
? ? ? ? {
? ? ? ? ? ? Sum[NOWI][t] = (r - l + 1) * c;
? ? ? ? ? ? Max[NOWI][t] = Min[NOWI][t] = c;
? ? ? ? ? ? mark[NOWI][t] = c;
? ? ? ? ? ? mks[NOWI][t] = 1;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? Sum[NOWI][t] += (r - l + 1) * c;
? ? ? ? ? ? Max[NOWI][t] += c;
? ? ? ? ? ? Min[NOWI][t] += c;
? ? ? ? ? ? mark[NOWI][t] += c;
? ? ? ? ? ? if(mks[NOWI][t] != 1) mks[NOWI][t] = 2;
? ? ? ? }
? ? ? ? return;
? ? }
? ? Pushdown(l ,r ,t);
? ? int mid = (l + r) >> 1;
? ? if(a <= mid) Update(lson ,a ,b ,c ,mk);
? ? if(b > mid) Update(rson ,a ,b ,c ,mk);
? ? Pushup(t);
? ? return;
}
NODE Query(int l ,int r ,int t ,int a ,int b)
{
? ? if(a <= l && b >= r)
? ? {
? ? ? ? NODE Ans;
? ? ? ? Ans.sum = Sum[NOWI][t];
? ? ? ? Ans.max = Max[NOWI][t];
? ? ? ? Ans.min = Min[NOWI][t];
? ? ? ? return Ans;
? ? }
? ? Pushdown(l ,r ,t);
? ? int tsum = 0 ,tmin = 1000000000 ,tmax = -1000000000;
? ? int mid = (l + r) >> 1;
? ? if(a <= mid)
? ? {
? ? ? ? NODE now = Query(lson ,a ,b);
? ? ? ? tsum += now.sum;
? ? ? ? if(tmin > now.min) tmin = now.min;
? ? ? ? if(tmax < now.max) tmax = now.max;
? ? }
? ? if(b > mid)
? ? {
? ? ? ? NODE now = Query(rson ,a ,b);
? ? ? ? tsum += now.sum;
? ? ? ? if(tmin > now.min) tmin = now.min;
? ? ? ? if(tmax < now.max) tmax = now.max;
? ? }
? ? NODE Ans;
? ? Ans.sum = tsum ,Ans.min = tmin ,Ans.max = tmax;
? ? return Ans;
}
int main ()
{
? ? int x1 ,y1 ,x2 ,y2 ,key ,v ,r ,c ,m ,i;
? ? while(~scanf("%d %d %d" ,&r ,&c ,&m))
? ? {
? ? ? ? BuidTree();
? ? ? ? while(m--)
? ? ? ? {
? ? ? ? ? ? scanf("%d" ,&key);
? ? ? ? ? ? if(key == 1)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? scanf("%d %d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2 ,&v);
? ? ? ? ? ? ? ? for(i = x1 ;i <= x2 ;i ++)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? NOWI = i;
? ? ? ? ? ? ? ? ? ? Update(1 ,c ,1 ,y1 ,y2 ,v ,2);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else if(key == 2)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? scanf("%d %d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2 ,&v);
? ? ? ? ? ? ? ? for(i = x1 ;i <= x2 ;i ++)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? NOWI = i;
? ? ? ? ? ? ? ? ? ? Update(1 ,c ,1 ,y1 ,y2 ,v ,1);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ?scanf("%d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2);
? ? ? ? ? ? ? ?NODE Ans ,NOW;
? ? ? ? ? ? ? ?for(i = x1 ;i <= x2 ;i ++)
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?NOWI = i;
? ? ? ? ? ? ? ? ? ?NOW = Query(1 ,c ,1 ,y1 ,y2);
? ? ? ? ? ? ? ? ? ?if(i == x1) Ans = NOW;
? ? ? ? ? ? ? ? ? ?else
? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ?Ans.sum += NOW.sum;
? ? ? ? ? ? ? ? ? ? ? ?Ans.max = maxx(Ans.max ,NOW.max);
? ? ? ? ? ? ? ? ? ? ? ?Ans.min = minn(Ans.min ,NOW.min);
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?printf("%d %d %d\n" ,Ans.sum ,Ans.min ,Ans.max);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
/*
4 4 8
1 1 2 4 4 5
3 2 1 4 4
1 1 1 3 4 2
3 1 2 4 4
3 1 1 3 4
2 2 1 4 4 2
3 1 2 4 4
1 1 1 4 3 3
45 0 5
78 5 7
69 2 7
39 2 7
*/
總結
以上是生活随笔為你收集整理的UVA11992不错的线段树段更新的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LA3644简单并查集判环
- 下一篇: UVA11384正整数序列(把123..