樹狀陣列與線段樹(三)

2021-10-02 10:23:03 字數 4365 閱讀 1903

找規律題

1.螺旋折線

如下圖所示的螺旋折線經過平面上所有整點恰好一次。

對於整點 (x,y)

,我們定義它到原點的距離 dis(x,y)

是從原點到 (x,y)

的螺旋折線段的長度。

例如 dis(0,1)=3,dis(−2,−1)=9

給出整點座標 (x,y)

,你能計算出 dis(x,y)

嗎?輸入格式

包含兩個整數 x,y。

輸出格式

輸出乙個整數,表示 dis(x,y)。

資料範圍

−109

≤x,y≤109

輸入樣例:

0 1
輸出樣例:
3

解題思路:這是一道找規律題,我們可以將整個座標都用距離標識一下,如下圖

我們先看x>=0&&y>=0時:若x>=y,dis=(2*x)*(2*x)+(x-y),若x

再看x<0&&y>0:x取絕對值,若x>=y,dis=(2*x-1)*(2*x)-(x-y),若x

再看x<=0&&y<=0:x取絕對值,y取絕對值,若x>=y&&x!=0&&y!=0,dis=(2*x-1)*(2*x-1)+(x-y),若x

其中需要特殊考慮x和y的負半軸,x!=0&&y==0,dis=(2*x-1)*(2*x-1)+(x-1),當x==0&&y!=0,dis=(2*y+1)*(2*y+1)-(y+1)

再看x>0&&y<0時:y取絕對值,當x<=y,dis=(2*y+1)*(2*y)+(y-x),當x>y時,dis=(2*x+1)*(2*x)-(x-y)

**:

#includeusing

namespace

std;

typedef

long

long

ll;int

main()

else

if(x<0&&y>0

)

else

if(x<=0&&y<=0

)

else

if(x0&&y!=0

) cout

<<(2*y+1)*(2*y+1)-(y+1-x)

if(x!=0&&y==0

) cout

<<(2*x-1)*(2*x-1)+(x-1)

if(x==0&&y!=0

) cout

<<(2*y+1)*(2*y+1)-(y+1)<}

else

if(x>0&&y<0

)

return0;

}

(二)差分

1.差分矩陣

輸入乙個n行m列的整數矩陣,再輸入q個操作,每個操作包含五個整數x1, y1, x2, y2, c,其中(x1, y1)和(x2, y2)表示乙個子矩陣的左上角座標和右下角座標。

每個操作都要將選中的子矩陣中的每個元素的值加上c。

請你將進行完所有操作後的矩陣輸出。

輸入格式

第一行包含整數n,m,q。

接下來n行,每行包含m個整數,表示整數矩陣。

接下來q行,每行包含5個整數x1, y1, x2, y2, c,表示乙個操作。

輸出格式

共 n 行,每行 m 個整數,表示所有操作進行完畢後的最終矩陣。

資料範圍

1≤n,m≤1000

1≤q≤100000

1≤x1≤x2≤n

1≤y1≤y2≤m

−1000≤c≤1000

−1000≤矩陣內元素的值≤1000

輸入樣例:

3 4 3

1 2 2 1

3 2 2 1

1 1 1 1

1 1 2 2 1

1 3 2 3 2

3 1 3 4 1

輸出樣例:
2 3 4 1

4 3 4 1

2 2 2 2

解題思路:差分矩陣是二維的,之前的差分陣列是一維的,他的解題思路與一維的思路是一樣的

核心:a[n][n],b[n][n],a陣列是b陣列的字首和

因此要在(x1,y1),(x2,y2)之間加上乙個數,則需要將

b[x1][y1]+=c;

b[x1][y2+1]-=c;

b[x2+1][y1]-=c;

b[x2+1][y2+1]+=c;

這樣才能滿足差分矩陣的要求

**:

#include#include

using

namespace

std;

const

int n=1010

;int

n,m,q;

inta[n][n],b[n][n];

void insert(int x1,int y1,int x2,int y2,int

c)int

main()

for(i=1;i<=n;i++)

for(j=1;j<=m;j++)

a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j];

for(i=1;i<=n;i++)

return0;

}

(三)線段樹

1.油漆面積

x星球的一批考古機械人正在一片廢墟上考古。

該區域的地面堅硬如石、平整如鏡。

管理人員為方便,建立了標準的直角座標系。

每個機械人都各有特長、身懷絕技。

它們感興趣的內容也不相同。

經過各種測量,每個機械人都會報告乙個或多個矩形區域,作為優先考古的區域。

矩形的表示格式為 (x1,y1,x2,y2)

,代表矩形的兩個對角點座標。

為了醒目,總部要求對所有機械人選中的矩形區域塗黃色油漆。

小明並不需要當油漆工,只是他需要計算一下,一共要耗費多少油漆。

其實這也不難,只要算出所有矩形覆蓋的區域一共有多大面積就可以了。

注意,各個矩形間可能重疊。

輸入格式

第一行,乙個整數 n

,表示有多少個矩形。

接下來的 n

行,每行有 4

個整數 x1,y1,x2,y2

,空格分開,表示矩形的兩個對角頂點座標。

輸出格式

一行乙個整數,表示矩形覆蓋的總面積。

資料範圍

1≤n≤10000

0≤x1,x2,y2,y2≤10000

資料保證 x1且 y1。輸入樣例1:

3

1 5 10 10

3 1 20 20

2 7 15 17

輸出樣例1:
340
輸入樣例2:
3

5 2 10 6

2 7 12 10

8 1 15 15

輸出樣例2:
128
**:

題解稍後補上

#include#include

#include

using

namespace

std;

const

int n=10010

;int

n;struct

segment

}seg[n*2

];struct

node

tr[n*4

];void pushup(int

u)void build(int u,int l,intr);

if(l==r)

return

;

int mid=l+r>>1

; build(u

<<1,l,mid),build(u<<1|1,mid+1

,r);

}void modify(int u,int l,int r,int

k)

else

}int

main()

; seg[m++]=;

}sort(seg,seg+m);

build(

1,0,10000

);

int res=0

;

for(int i=0;i)

printf("%d

",res);

return0;

}

樹狀陣列與線段樹

推一下關於樹狀陣列的講解部落格 和線段樹的講解 package test2 public class 線段樹 int len a.length segtree t buildtree 0,len 1,a int sum0 2 query t,0,2 int sum1 3 query t,1,3 查詢...

樹狀陣列與線段樹(二)

樹狀陣列 1.小朋友排隊 n n 個小朋友站成一排。現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。每個小朋友都有乙個不高興的程度。開始的時候,所有小朋友的不高興程度都是 0 0 如果某個小朋友第一次被要求交換,則他的不高興程度增加 1 1 如果第二次要求他交換,則他的不...

線段樹與樹狀陣列學習總結 線段樹

點動成線 那麼就是說一條線段可以分成若干個點,再想想我們最常用的一維陣列,構成陣列的是乙個個的變數,如果把變數看成乙個個點,那麼陣列就是一條線了!而線段樹,就是一棵由線段構成的二叉樹,每個結點都代表一條線段 a,b 也就是我們前面說的一串變數 非葉子的結點所對應的線段都有兩個子結點,左兒子代表的線段...