NOI省選模擬 小奇的花園

2022-08-04 09:03:09 字數 3541 閱讀 6866

「題目背景」

小奇在家中的花園漫步時,總是會思考一些奇怪的問題。

「問題描述」

小奇的花園有n個溫室,標號為1到n,溫室以及以及溫室間的雙向道路形成一棵樹。

每個溫室都種植著一種花,隨著季節的變換,溫室裡的花的種類也在不斷發生著變化。

小奇想知道從溫室x走到溫室y的路徑中(包括兩個端點),第t種花出現的次數。

「輸入格式」

第一行為兩個整數n,q,表示溫室的數目和操作的數目。

第二行有n個整數t1,t2…tn其中ti表示溫室i中的花的種類。

接下來n-1行,每個兩個整數x, y,表示溫室x和y之間有一條雙向道路。

接下來q行,表示q個操作,分別為以下兩種形式之一:

• c x t 表示在溫室x中的花的種類變為t。

• q x y t 表示詢問溫室x走到溫室y的路徑中(包括兩個端點),第t種花出現

的次數。

「輸出格式」

輸出q行,每行乙個正整數表示該次詢問答案。

「樣例輸入」

5 8

10 20 30 40 50

1 21 3

3 43 5

q 2 5 10

c 2 21

q 3 4 21

c 6 22

q 1 7 28

c 5 20

q 2 5 20

q 2 0 9

「樣例輸出」

120

31

「樣例解釋」加密前的操作:

q 2 5 10

c 3 20

q 2 5 20

c 4 20

q 3 5 30

c 5 20

q 2 5 20

q 1 3 10

「資料範圍」

對於30%的資料,有n <= 1000, q <= 2000。

對於50%的資料,有n <= 10000, q <= 20000。

對於100%的資料,有n <= 100000, q <= 200000,0 <= t < 2^31。

←小奇

下面的題解都是自己的話:

50%

考場上實在沒辦法ac拿50分也不吃虧。

100%

有乙個轉化很重要。

我們可以通過類似求樹上兩點路徑長度 dis=dep[x]+dep[y]-dep[lca]*2 的方法,用s[i]表示從根節點到此時的i點col顏色的出現次數。

所以每次在某個節點的某個顏色出現次數增加1時,它的整個子樹的每個節點的s[i]都會增加1,那麼從x到y某個顏色的出現次數顯然就變成 s[x]+s[y]-s[lca]*2+val[lca]了

那這樣題目要求的單點修改、區間查詢就被我們變成子樹修改、單點查詢了。子樹修改用dfs序來看其實也就是區間修改了,可以用線段樹解決。

但是顏色種類那麼多怎麼辦呢(而且數值還那麼大)?

可以用map來維護顏色編號,用動態開點線段樹的方式對每一種顏色維護一棵線段樹。

做本題是參考了黃學長hzwer的題解和程式,**可能有相似之處,但線段樹的操作絕對是我自己的風格。(求資瓷~)

1 #include2 #include3 #include4 #include5 #include6 #include7

8#define for(i,a,b)for(register int i=a;i<=b;++i)

9#define dwn(i,a,b)for(register int i=a;i>=b;--i)

10#define re register

11#define pn putchar('\n')

1213

using

namespace

std;

1415

const

int n=1e5+5,nr=1e7+5;16

int head[n],nxt[n*2],v[n*2],cnt=1;17

int f[n][21],dfx[n],did=0

,dep[n],sz[n];

18int rt[n*3],ls[nr],rs[nr],tag[nr],tr[nr],tid=0;19

int n,m,x,y,t[n*3],cid=0,t,q,ans=0

;20 mapmp;

21 inline void read(int &v)

27void write(int

x)32

void add(int ux,int

vx)38

39void dfs(int x,int

fa)50}51

52int lca(int x,int

y)57

if(x==y)return

x;58 dwn(b,20,0)if(f[x][b]!=-1&&f[y][b]!=-1&&f[x][b]!=f[y][b])

61return f[x][0

];62}63

6465

void pdown(int o,int l,int

r)73

74void ins(int &o,int l,int r,int lx,int rx,int

dt)80

pdown(o,l,r);

81int m=(l+r)>>1;82

if(lx<=m)ins(ls[o],l,m,lx,rx,dt);

83if(rx>m)ins(rs[o],m+1

,r,lx,rx,dt);84}

8586

int qry(int o,int l,int r,int

px)94

9596

intmain()

105 for(i,1,n-1

)109

110 memset(f,-1,sizeof

(f));

111 dfs(1,0

);112 for(b,1,20) for(i,1

,n)116

117 for(i,1

,n)122

123 for(i,1

,q)138

if(opt=='q'

)151

}152

fclose(stdin); fclose(stdout);

153return0;

154 }

Luogu U16325小奇的花園(樹鏈剖分)

題目鏈結 學了學動態開點的樹鏈剖分,其實跟動態開點的線段樹差不多啦 查詢的時候別ssbb地動態開點,如果沒這個點果斷返回0就行 只要注意花的種類能到intmax就行qwq!include include include include include include define mid l r 1...

JZOJ 省選模擬 夕張的改造 kaisou

description 提督們驚奇地發現,2019 年實裝的改造非常少。經調查,原來是改造廠的廠長於八日剋扣了其他艦娘改造的圖紙,並且在 2020 年的第乙個月利用這些圖紙進行了華麗的改造,一共有三種形態,於八日改二,於八日改二特,於八日改二丁,對空 對陸 對潛 開幕雷 五裝備格,無所不能。鎮守府雪...

BSOJ3392 省選模擬 樹上的詢問

bsoj3392 省選模擬 樹上的詢問 點分治。點分治入門題,首先這題可以直接做,也可以轉化成 小於等於 k 的減掉 小於等於 k 1 的 然後相減來做。兩者皆可。includeusing namespace std define ll long long define ull unsigned l...