hdu 4358 深搜時間戳 線段樹更新

2022-07-28 21:27:22 字數 2003 閱讀 7733

其實這道題真的告訴了我乙個道理,那就是仔細看題,題目中明確說出了1就是所有子樹的根結點。

我們可以想一想,現在每個結點代表著一段區間的詢問,所以我們必須利用深搜的時間戳來找出所有結點所代表的區間。

前向星見圖自然不可少。

更新區間的話,我們必須用離線處理,[i,j]這個區間代表著第i個數在這個區內出現k次的數的個數。

view code

1 #include2 #include3 #include

4 #include5 #include6 #include7 #include8

using

std::sort;

9using

std::vector;

10using

std::map;

11const

int n = 100111

;12 mapq;

13 vectorp[n];

14struct

edge

15edge[n<<1

];18

inthead[n],weight[n],visit[n],ti;

19struct

query

2026

}que[n];

27struct

node

28no[n];

31int cover[n<<2

],num[n],ans[n];

32void dfs(int

u)3344}

45 no[u].r=ti;46}

47void pushdown(int

t)48

56return;57

}58void update(int t,int l,int r,int l,int r,int

val)

5965

pushdown(t);

66int m=(r+l)>>1;67

if(l<=m)update(t<<1

,l,m,l,r,val);

68if(r>m)update(t<<1|1,m+1

,r,l,r,val);69}

70int query(int t,int l,int r,int

i)71

78int

main()

7995

int tope=0;96

for(int i=0;i)

97p[i].clear();

98for(int i=1;i)

99108 visit[1]=ti=1

;109 dfs(1

);110 scanf("

%d",&q);

111for(int i=1;i<=q;i++)

112118 sort(que+1,que+q+1

);119 memset(cover,0,sizeof

(cover));

120for(int i=1,j=1;i<=n;i++)

121129

else

130if(count==k)

131 update(1,1,n,1,p[num[i]][count-k],1

);132

while(i>=que[j].r)

133138

if(j>q)break

;139

}140

if(t!=0)printf("\n"

);141 printf("

case #%d:\n

",++t);

142for(int i=1;i<=q;i++)

143 printf("

%d\n

",ans[i]);

144}

145return0;

146 }

hdu4358 樹狀陣列 非常經典

碰到過類似這題幾次都做不出,只因為始終不理解 1.深搜後樹上的某點的子樹變成陣列的乙個區間,網上有人估計寫挫了,說會爆棧,我不會,最好不用vector,會tle,這題資料挺強的,後來改了鄰接表過了,事實證明,鄰接表還是時間空間都有很好效果的做法 2.講詢問按右端點排序,每次插入更新,如果有這個是某個...

hdu 4358 莫隊演算法 dfs序列

解題思路 用dfs求出整棵樹的dfs序列,這樣以u為根節點的子樹就轉化到相對應的區間上了。由於是區間不修改查詢問題,這個時候就可以用莫隊演算法了。pragma comment linker,stack 16777216 include include include include includeu...

hdu 1010 深搜 回溯

也不想解釋了,只是做來找回做題的感覺。遲d出個這方面的小總結,越來越發現對所學知識作總結的重要性了 1010tempter of the bone include includeint n,m,time int xs,ys,xd,yd int direc 4 2 char str 11 11 boo...