1. 一、区间划分
  2. //区间划分+持久化并查集:区间连通情况统计。
  3. inline bool comp(Ask x, Ask y){return x.km == y.km ? x.l > y.l : x.km > y.km ; }
  4. inline void init()//把编号相同的放一起,l从大到小;{
  5. int i ;
  6. ms = sqrt(1.0*n) ; //大小
  7. mg = n/ms ; //块数
  8. mg = mg*ms == n ? mg : mg + ;
  9. for(i = ; i <= n ; i ++) e[i].clear() ;
  10. }
  11. /*********************持久化并查集**********************************/
  12. void solve()//区间划分{
  13. int i = , j, k, l, r ;
  14. sort(ask+, ask++q, comp) ;
  15. while(i <= q) //询问
  16. {
  17. k = ask[i].km ;
  18. for(; i <= q && ask[i].km == k && ask[i].l > (k-)*ms ; i ++) //处理区间小于ms的询问
  19. ans[ask[i].no] = bfAnswer(i) ;
  20. if(i > q || ask[i].km != k ) //全部为小区间
  21. continue ;
  22. r = (k-)*ms ; //最右端
  23. initSet(lp, , r) ; //初始化并查集 ;
  24. for(j = ; j <= r ; j ++) vis[j] = ;
  25. while(i <= q && ask[i].km == k ) //求解第k块的所有大询问;
  26. {
  27. l = ask[i].l ;
  28. for(j = r ; j >= l ; j -- ) //加入顶点j
  29. addVex(lp, j, (k-)*ms) ;
  30. r = j ;
  31. for(; i <= q && ask[i].km == k && ask[i].l == l ; i ++)
  32. //计算所有左端等于l的区间;
  33. {
  34. ans[ask[i].no] = unionRSet(ask[i].no, l, (k-)*ms+, ask[i].r ) ; //右端暴力合并 ;
  35. }
  36. }
  37. }
  38. }
  39. 二、2B树:动态区间比x小的数的个数。
  40. void DT_insert(int rt, int x, int s ){
  41. int i = DN, j, p ;
  42. getBinary(x) ;
  43. j = dig[i--] ;
  44. if(root[rt].next[j] == -)
  45. {
  46. root[rt].next[j] = ++ tot ;
  47. pool[tot].set() ;
  48. }
  49. if(!j) root[rt].sum += s ;
  50. p = root[rt].next[j] ;
  51. while(i)
  52. {
  53. j = dig[i--] ;
  54. if(pool[p].next[j] == -)
  55. {
  56. pool[p].next[j] = ++ tot ;
  57. pool[tot].set() ;
  58. }
  59. if(!j)pool[p].sum += s ;
  60. p = pool[p].next[j] ;
  61. }
  62. }
  63. int DT_count(int rt, int x){
  64. int i = DN, j, p, ans = ;
  65. getBinary(x) ;
  66. j = dig[i--] ;
  67. if(j) ans += root[rt].sum ;
  68. if(root[rt].next[j] == -) return ans ;
  69. p = root[rt].next[j] ;
  70. while(i)
  71. {
  72. j = dig[i--] ;
  73. if(j) ans += pool[p].sum ;
  74. if(pool[p].next[j] == -) return ans ;
  75. p = pool[p].next[j] ;
  76. }
  77. return ans ;
  78. }
  79. void DT_build(){
  80. int i, k ;
  81. size = sqrt(double(n)) ;
  82. mg = n/size ;
  83. mg = mg*size == n ? mg : mg+ ;
  84. for(i = ; i <= mg ; i ++) root[i].set() ;
  85. for(i = ; i <= n ; i ++)
  86. {
  87. k = (i-)/size + ;
  88. DT_insert(k, ar[i], ) ;
  89. }
  90. bs = *size ;
  91. bmg = n/bs ;
  92. bmg = bmg*bs == n ? bmg : bmg + ;
  93. for(i = ; i <= bmg+ ; i ++) root[MAXS+i].set() ;
  94. for(i = ; i <= n ; i ++)
  95. {
  96. k = (i-)/bs + ;
  97. DT_insert(MAXS+k, ar[i], ) ;
  98. }
  99. }
  100. int DT_query(int l, int r, int x){
  101. int i, k, ans = , bk ;
  102. k = (l-)/size + ;
  103. k = size*(k-)+ == l ? k : k + ; //前
  104. for(i = l ; i <= r && i < (k-)*size+ ; i ++) ans = ar[i] < x ? ans+ : ans ;
  105. for(; i <= r && r-i+ >= size && (k% != ) ; i += size, k ++) //小块
  106. ans += DT_count(k, x) ;
  107. for(bk = (k-)/+ ; i <= r && r-i+ >= bs ; i += bs, bk ++, k += )
  108. ans += DT_count(MAXS+bk, x) ;//大块
  109. for(; i <= r && r-i+ >= size ; i += size, k ++) //小块
  110. ans += DT_count(k, x) ;
  111. for(; i <= r ; i ++) ans = ar[i] < x ? ans+ : ans ;
  112. return ans ;
  113. }
  114. 三、树链剖分
  115. . 树上区间[u, v] 异或 x 的最大值
  116. // 持久化2B树 + 树链剖分(区间可直接合并)
  117. inline void insert(int rt, int x) //建一颗空树
  118. inline void addNumber(int pre, int &rt, int id, int x){//持久化
  119. int i = SD, p ;
  120. bool j ;
  121. rt = ++dcnt ; p = rt ;
  122. while(i >= )
  123. {
  124. pool[p] = pool[pre] ;
  125. j = x&(<<i) ;
  126. pool[p].mx[j] = id ;
  127. pool[p].next[j] = ++dcnt ;
  128. p = dcnt ;
  129. pre = pool[pre].next[j] ;
  130. i -- ;
  131. }
  132. pool[p].x = x ;
  133. }
  134. inline int DTcount(int rt,int l,int x)//计算前缀树[1,r]中下标>=l的与x的最大异或值
  135. /*******c******************树链剖分*************************/
  136. void DFS(int u){
  137. int i, to ;
  138. siz[u] = ; son[u] = ;
  139. for(i = head[u] ; i != - ; i = e[i].next )
  140. {
  141. to = e[i].to ;
  142. if(to != fa[u])
  143. {
  144. fa[to] = u ;
  145. dep[to] = dep[u] + ;
  146. DFS(to) ;
  147. if(siz[son[u]] < siz[to]) son[u] = to ;
  148. siz[u] += siz[to] ;
  149. }
  150. }
  151. }
  152. void cutLink(int u, int tp){
  153. w[u] = ++cnt ;
  154. top[u] = tp ;
  155. if(son[u]) cutLink(son[u], tp) ;
  156. for(int i = head[u] ; i != - ; i = e[i].next)
  157. {
  158. int to = e[i].to ;
  159. if(to != fa[u] && to != son[u]) cutLink(to, to) ;
  160. }
  161. }
  162. void buildTree(){
  163. dep[] = ;
  164. cnt = fa[] = siz[] = ;
  165. DFS() ;
  166. cutLink(, ) ;
  167. int i ;
  168. for(i = ; i <= n ; i ++) val[w[i]] = ar[i] ;
  169. pool[].set() ;
  170. dcnt = T[] = ;
  171. for(i = ; i <= cnt ; i ++) insert(T[], val[i]) ;
  172. for(i = ; i <= cnt ; i ++) addNumber(T[i-], T[i], i, val[i]) ;//持久化思
  173. }
  174. int getAns(int u, int v, int x){
  175. int ans = , tu = top[u], tv = top[v], tmp ;
  176. if(u == v) return DTcount(T[w[u]], w[v], x) ; ;
  177. while(tu != tv) //如果不在同一条链上
  178. {
  179. if(dep[tu] < dep[tv]) {swap(tu, tv) ; swap(u, v) ; }
  180. tmp = DTcount(T[w[u]], w[tu], x ) ; //查询从u到tu的父亲的最大值
  181. ans = max(ans, tmp) ;
  182. u = fa[tu] ;
  183. tu = top[u] ;
  184. }
  185. if(dep[u] < dep[v]) swap(u, v) ;
  186. tmp = DTcount(T[w[u]], w[v], x) ;
  187. return max(ans, tmp) ;
  188. }
  189. . BFS实现建树
  190. int leaf[MAXN], ns[MAXN], ct[MAXN];
  191. void BFS(int rt){
  192. int i, h = , t = , l = , r = ;
  193. int u, to ;
  194. que[t++] = rt ;
  195. for(i = ; i <= n ; i ++)
  196. {
  197. siz[i] = ;
  198. ct[i] = ns[i] = son[i] = ;
  199. }
  200. while (h < t) // calculate the dep.
  201. {
  202. u = que[h++] ;
  203. for(i = head[u] ; i != - ; i = e[i].next)
  204. {
  205. to = e[i].to ;
  206. if(to != fa[u])
  207. {
  208. ns[u] ++ ;
  209. fa[to] = u ;
  210. dep[to] = dep[u] + ;
  211. que[t++] = to ;
  212. }
  213. }
  214. }
  215. for(i = ; i <= n ; i ++) if(ns[i] == ) leaf[r++] = i ;
  216. while(l < r)
  217. {
  218. to = leaf[l++] ;
  219. u = fa[to] ;
  220. siz[u] += siz[to] ; ct[u] ++ ;
  221. if(ct[u] == ns[u] && u ) leaf[r++] = u ;
  222. }
  223. h = t = ;
  224. que[t++] = rt ;
  225. siz[] = ;
  226. while (h < t)
  227. {
  228. u = que[h++] ;
  229. for(i = head[u] ; i != - ; i = e[i].next)
  230. {
  231. to = e[i].to ;
  232. if(to != fa[u])
  233. {
  234. if(siz[son[u]] < siz[to]) son[u] = to ;
  235. que[t++] = to ;
  236. }
  237. }
  238. }
  239. }
  240. void BFS_cutLink(int rt, int tp){
  241. int i, u, to, h = , t = ;
  242. que[t++] = rt ;
  243. while (h < t)
  244. {
  245. u = que[h++] ;
  246. w[u] = ++cnt ; top[u] = u ;
  247. to = son[u] ;
  248. while (to)
  249. {
  250. w[to] = ++cnt ; top[to] = u ;
  251. for(i = head[to] ; i != - ; i = e[i].next)
  252. if(e[i].to != fa[to] && e[i].to != son[to]) que[t ++] = e[i].to ;
  253. to = son[to] ;
  254. }
  255. for(i = head[u] ; i != - ; i = e[i].next)
  256. {
  257. to = e[i].to ;
  258. if(to != fa[u] && to != son[u]) que[t++] = to ;
  259. }
  260. }
  261. }
  262. . 非直接合并查询:树上最长上升子序列
  263. /*********************线段树成段更新最长上升子序列*************************/
  264. void Up(int step){
  265. L[step].lx = L[lson].lx + ( (L[lson].lx==L[lson].len && val[L[rson].left] > val[L[lson].right])?L[rson].lx:) ;
  266. L[step].rx = L[rson].rx + ((L[rson].rx==L[rson].len &&val[L[rson].left] > val[L[lson].right])?L[lson].rx:) ;
  267. L[step].mx = max(max(L[lson].mx,L[rson].mx),val[L[rson].left]
  268. > val[L[lson].right]?(L[lson].rx+L[rson].lx):);
  269.  
  270. L[step].dlx = L[lson].dlx + ( (L[lson].dlx == L[lson].len && val[L[rson].left] < val[L[lson].right]) ? L[rson].dlx : );
  271. L[step].drx = L[rson].drx + ((L[rson].drx == L[rson].len && val[L[rson].left] < val[L[lson].right]) ? L[lson].drx : ) ;
  272. L[step].dmx = max(max(L[lson].dmx,L[rson].dmx),val[L[rson].left]
  273. < val[L[lson].right] ? (L[lson].drx+L[rson].dlx) : ) ;
  274. }
  275. void build(int step,int l,int r){
  276. L[step].left=l;
  277. L[step].right=r;
  278. L[step].len = r-l+ ;
  279. L[step].mid=(l+r)/;
  280. if(l==r)
  281. {
  282. L[step].lx = L[step].rx = L[step].mx = ;
  283. L[step].dlx =L[step].drx = L[step].dmx = ;
  284. return ;
  285. }
  286. ……
  287. }
  288. inline void unionNode(int l, int r, int ar ){
  289. L[ar].lx = L[l].lx + ((L[l].lx==L[l].len && val[L[r].left]
  290. > val[L[l].right]) ? L[r].lx : ) ;
  291. L[ar].rx = L[r].rx + ((L[r].rx==L[r].len && val[L[r].left]
  292. > val[L[l].right]) ? L[l].rx : ) ;
  293. L[ar].mx = max(max(L[l].mx,L[r].mx),val[L[r].left]
  294. > val[L[l].right]?(L[l].rx+L[r].lx):);
  295.  
  296. L[ar].dlx = L[l].dlx + ((L[l].dlx == L[l].len && val[L[r].left]
  297. < val[L[l].right]) ? L[r].dlx : );
  298. L[ar].drx = L[r].drx + ((L[r].drx == L[r].len && val[L[r].left]
  299. < val[L[l].right]) ? L[l].drx : ) ;
  300. L[ar].dmx = max(max(L[l].dmx,L[r].dmx),val[L[r].left] < val[L[l].right]
  301. ? (L[l].drx+L[r].dlx) : ) ;
  302. L[ar].left = L[l].left ;
  303. L[ar].right = L[r].right ;
  304. L[ar].len = L[l].len + L[r].len ;
  305. }
  306. int query(int step,int l,int r){
  307. if(l==L[step].left&&r==L[step].right) return step ;
  308. ……
  309. else {
  310. int lt = query(lson,l,L[step].mid);
  311. int rt = query(rson,L[step].mid+,r);
  312. ++scnt ;
  313. unionNode(lt, rt, scnt) ;
  314. return scnt ;
  315. }
  316. }
  317. /*************************树链剖分*************************/
  318. inline int unionAns(int l, int r){
  319. int tmp = max(L[l].dmx, L[r].mx), ans ;
  320. if(val[L[l].left] < val[L[r].left]) ans = L[r].lx + L[l].dlx ;
  321. else ans = ;
  322. ans = max(tmp, ans) ;
  323. return ans ;
  324. }
  325. int getAns(int u, int v){
  326. if(u == v) return L[query(, w[u], w[u])].mx ;
  327. int tu = top[u], tv = top[v] ;
  328. int ar, tr, ur, vr ;
  329. scnt = *cnt +;
  330. ar = ++scnt ; ur = - ; vr = - ;
  331. while (tu != tv)
  332. {
  333. if(dep[tu] > dep[tv])//calculate the link tu -> u.
  334. {
  335. tr = query(, w[tu], w[u]) ;
  336. if(ur == -) ur = tr ;
  337. else {
  338. ++scnt ;
  339. unionNode(tr, ur, scnt); //tr is left node.
  340. ur = scnt ;
  341. }
  342. u = fa[tu] ; tu = top[u] ;
  343. }
  344. else {
  345. tr = query(, w[tv], w[v]) ;
  346. if(vr == -) vr = tr ;
  347. else {
  348. ++scnt ;
  349. unionNode(tr, vr, scnt) ; // tr is left node.
  350. vr = scnt ;
  351. }
  352. v = fa[tv] ; tv = top[v] ;
  353. }
  354. }
  355. if(dep[u] >= dep[v])// v is root.
  356. {
  357. tr = query(, w[v], w[u]) ;
  358. if(ur == -) ur = tr ;
  359. else {
  360. scnt ++ ;
  361. unionNode(tr, ur, scnt) ;
  362. ur = scnt ;
  363. }
  364. u = v ;
  365. }
  366. else {
  367. tr = query(, w[u], w[v]) ;
  368. if(vr == -) vr = tr ;
  369. else {
  370. ++scnt ;
  371. unionNode(tr, vr, scnt) ;
  372. vr = scnt ;
  373. }
  374. v = u ;
  375. }
  376. if(ur == -) return L[vr].mx ;
  377. else if(vr == -) return L[ur].dmx ;
  378. return unionAns(ur, vr) ; // calculate the answer of u->v
  379. }
  380. . 树上最大字段和
  381. /*********************线段树最大子段和*************************/
  382. inline void Up(int rt){
  383. sum[rt] = sum[rt<<] + sum[rt<<|] ;
  384. lx[rt] = max(lx[rt<<|], lx[rt<<] + sum[rt<<|]) ;
  385. rx[rt] = max(rx[rt<<], rx[rt<<|] + sum[rt<<]) ;
  386. mx[rt] = max(mx[rt<<], mx[rt<<|]) ;//不合并
  387. mx[rt] = max(mx[rt], lx[rt<<] + rx[rt<<|]) ; //合并
  388. }
  389. inline void Down(int rt, int L, int R){
  390. if(d[rt] != INF)
  391. {
  392. int x = d[rt] ;
  393. int mid = (L+R) >> ;
  394. d[rt] = INF ;
  395. d[rt<<] = d[rt<<|] = x ;
  396. sum[rt<<] = (LL)x*(mid-L+) ;
  397. sum[rt<<|] = (LL)x*(R-mid) ;
  398. lx[rt<<] = rx[rt<<] = mx[rt<<] = x > ? sum[rt<<] : ;
  399. lx[rt<<|] = rx[rt<<|] = mx[rt<<|] = x > ? sum[rt<<|] : ;
  400. }
  401. }
  402. inline void unionNode(int l, int r, int ar ){
  403. sum[ar] = sum[l] + sum[r] ;
  404. lx[ar] = max(lx[r], lx[l]+sum[r]) ;
  405. rx[ar] = max(rx[l], rx[r]+sum[l]) ;
  406. mx[ar] = max(mx[l], mx[r]) ;
  407. mx[ar] = max(mx[ar], lx[l]+rx[r]) ;
  408. }
  409. void build(int rt, int l, int r){
  410. d[rt] = INF ;
  411. if(l == r)
  412. {
  413. sum[rt] = lx[rt] = rx[rt] = mx[rt] = val[l] ;
  414. return ;
  415. }
  416. ……
  417. }
  418. void updata(int rt, int L, int R, int l, int r, int x){
  419. if(L == l && r == R)
  420. {
  421. sum[rt] = (R-L+)*x ;
  422. lx[rt] = rx[rt] = mx[rt] = x > ? sum[rt] : ;
  423. d[rt] = x ;
  424. return ;
  425. }
  426. Down(rt, L, R) ;
  427. ……
  428. }
  429. int query(int rt, int L, int R, int l, int r){
  430. if(L == l && R == r) return rt ;
  431. Down(rt, L, R) ;
  432. ……
  433. else {
  434. int x = query(rt<<, L, mid, l, mid) ;
  435. int y = query(rt<<|, mid+, R, mid+, r) ;
  436. ++scnt ;
  437. unionNode(x, y, scnt) ;
  438. return scnt ;
  439. }
  440. }
  441. /*************************树链剖分*************************/
  442. inline void unionAns(int x, int y, int ar){
  443. mx[ar] = max(mx[x], mx[y]) ;
  444. mx[ar] = max(mx[ar], rx[x]+rx[y]) ;
  445. }
  446. int getAns(int u, int v){
  447. if(u == v) return query(, , cnt, w[u], w[u]) ;
  448. int tu = top[u], tv = top[v] ;
  449. int ar, tr, ur, vr ;
  450. scnt = *cnt +;
  451. ar = ++scnt ; ur = - ; vr = - ;
  452. while (tu != tv)
  453. {
  454. if(dep[tu] > dep[tv])//calculate the link tu -> u.
  455. {
  456. tr = query(, , cnt, w[tu], w[u]) ;
  457. if(ur == -) ur = tr ;
  458. else {
  459. ++scnt ;
  460. unionNode(tr, ur, scnt); //tr is left node.
  461. ur = scnt ;
  462. }
  463. u = fa[tu] ; tu = top[u] ;
  464. }
  465. else {
  466. tr = query(, , cnt, w[tv], w[v]) ;
  467. if(vr == -) vr = tr ;
  468. else {
  469. ++scnt ;
  470. unionNode(tr, vr, scnt) ; // tr is left node.
  471. vr = scnt ;
  472. }
  473. v = fa[tv] ; tv = top[v] ;
  474. }
  475. }
  476. if(dep[u] >= dep[v])
  477. {
  478. tr = query(, , cnt, w[v], w[u]) ;
  479. if(ur == -) ur = tr ;
  480. else {
  481. scnt ++ ;
  482. unionNode(tr, ur, scnt) ;
  483. ur = scnt ;
  484. }
  485. u = v ;
  486. }
  487. else {
  488. tr = query(, , cnt, w[u], w[v]) ;
  489. if(vr == -) vr = tr ;
  490. else {
  491. ++scnt ;
  492. unionNode(tr, vr, scnt) ;
  493. vr = scnt ;
  494. }
  495. v = u ;
  496. }
  497. if(ur == -) return vr ;
  498. else if(vr == -) return ur ;
  499. unionAns(ur, vr, ar) ; // calculate the answer of u->v
  500. return ar ;
  501. }
  502. 四、持久化线段树
  503. /*******************静态 Kth number ***************************************/
  504. void build(int &rt, int l, int r ){
  505. rt = ++tot ;
  506. sum[rt] = ;
  507. if(l >= r) return ;
  508. ……
  509. }
  510. void updata(int &rt, int pre, int l, int r, int i, int v){
  511. rt = ++tot ;
  512. ls[rt] = ls[pre] ; rs[rt] = rs[pre] ; sum[rt] = sum[pre] + v ;
  513. if(l >= r ) return ;
  514. int mid = l+r >> ;
  515. if(mid >= i ) updata(ls[rt], ls[pre], l, mid, i, v) ;
  516. else updata(rs[rt], rs[pre], mid+, r, i, v) ;
  517. }
  518. int query(int R, int L, int l, int r, int k){
  519. if(l >= r) return l ;
  520. int t = sum[ls[R]] - sum[ls[L]] ;
  521. int mid = l+r >> ;
  522. if(t >= k) return query(ls[R], ls[L], l, mid, k) ;
  523. else return query(rs[R], rs[L], mid+, r, k-t) ;
  524. }
  525. /***************************************************************/
  526. void solve(){
  527. sort(ord+, ord++n, comp) ;
  528. cnt = rk[ord[]] = ;
  529. nar[cnt] = ar[ord[]] ;
  530. for(i = ; i <= n ; i ++)
  531. {
  532. if(ar[ord[i]] != ar[ord[i-]])
  533. {
  534. rk[ord[i]] = ++cnt ;
  535. nar[cnt] = ar[ord[i]] ;
  536. }
  537. else rk[ord[i]] = cnt ;
  538. }
  539. tot = ;
  540. build(T[], , cnt) ;
  541. for(i = ; i <= n ; i ++) updata(T[i], T[i-], , cnt, rk[i], ) ;
  542. for(i = ; i <= m ; i ++)
  543. {
  544. scanf("%d %d %d", &l, &r, &k) ;
  545. ans = query(T[r], T[l-], , cnt, k) ;
  546. printf("%d\n", nar[ans]) ;//离散后的数组
  547. }
  548. }
  549. }
  550. 五、KD
  551. #define N 50005
  552. #define MID(x,y) ( (x + y)>>1 )
  553. using namespace std ;
  554. typedef long long LL ;
  555. struct Point{
  556. int x[];
  557. LL dis;
  558. Point(){
  559. for(int i = ; i < ; i++) x[i] = ;
  560. dis = 9223372036854775807LL ;
  561. }
  562. friend bool operator < (const Point &a, const Point &b)
  563. { return a.dis < b.dis ; }
  564. };
  565. priority_queue <Point, vector<Point> > res ;
  566. LL dist2(const Point &a, const Point &b, int k) {
  567. //距离的平方,开根号很耗时,能不开就不开
  568. LL ans = ;
  569. for (int i = ; i < k; i++)
  570. //一开始这儿写的i < 5,WA了N次。。。原本以为只要初始值设0就无所谓,
  571. ans += (a.x[i] - b.x[i]) * (a.x[i] - b.x[i]);
  572. //但发现Point有个全局变量,在多case下会出错。。。
  573. return ans;
  574. }
  575. int ddiv;
  576. bool cmpX(const Point &a, const Point &b){return a.x[ddiv] < b.x[ddiv];}
  577. struct KDTree {
  578. Point p[N]; //空间内的点
  579. int Div[N];
  580. //记录区间是按什么方式划分(分割线平行于x轴还是y轴, ==1平行y轴切;==0平行x轴切)
  581. int k; //维数
  582. int m; //近邻
  583. int getDiv(int l, int r) { //寻找区间跨度最大的划分方式
  584. map <int, int> ms;
  585. int minx[],maxx[];
  586. for (int i = ; i < k; i++)
  587. {
  588. ddiv = i;
  589. minx[i] = min_element(p + l, p + r + , cmpX)->x[i];
  590. maxx[i] = max_element(p + l, p + r + , cmpX)->x[i];
  591. ms[maxx[i] - minx[i]] = i;
  592. }
  593. map <int ,int>::iterator pm = ms.end();
  594. pm--;
  595. return pm->second;
  596. }
  597. void build(int l, int r) { //记得先把p备份一下。
  598. if (l > r) return;
  599. int mid = MID(l,r);
  600. Div[mid] = getDiv(l,r);
  601. ddiv = Div[mid];
  602. nth_element(p + l, p + mid, p + r + , cmpX);
  603. build(l, mid - );
  604. build(mid + , r);
  605. }
  606. void findk(int l, int r, Point a) {//k(m)近邻,查找k近点的平方距离
  607. if (l > r) return;
  608. int mid = MID(l,r);
  609. LL dist = dist2(a, p[mid], k);
  610. if (dist >= )
  611. {
  612. p[mid].dis = dist;
  613. res.push(p[mid]);
  614. while ((int)res.size() > m)
  615. res.pop();
  616. }
  617. LL d = a.x[Div[mid]] - p[mid].x[Div[mid]];
  618. int l1, l2, r1, r2;
  619. l1 = l , l2 = mid + ;
  620. r1 = mid - , r2 = r;
  621. if (d > )
  622. swap(l1, l2), swap(r1, r2);
  623. findk(l1, r1, a);
  624. if ((int)res.size() < m || d*d < res.top().dis )
  625. findk(l2, r2, a);
  626. }
  627. };
  628. Point pp[N];
  629. KDTree kd;
  630. int solve(){
  631. for (int i = ; i < n; i++)
  632. for (int j = ; j < kd.k; j++)
  633. {
  634. scanf("%d", &pp[i].x[j]);
  635. kd.p[i] = pp[i];
  636. }
  637. kd.build(, n - );
  638. int t = ;
  639. while(t--)
  640. {
  641. Point a;
  642. for (int i = ; i < kd.k; i++)scanf("%d", &a.x[i]);
  643. scanf("%d", &kd.m);
  644. kd.findk(, n - , a);
  645. printf("the closest %d points are:\n", kd.m);
  646. Point ans[];
  647. for (int i = ; !res.empty(); i++)
  648. {
  649. ans[i] = res.top();
  650. res.pop();
  651. }
  652. for (int i = kd.m - ; i >= ; i--)
  653. {
  654. for (int j = ; j < kd.k - ; j++)
  655. printf("%d ", ans[i].x[j]);
  656. printf("%d\n", ans[i].x[kd.k - ]);
  657. }
  658. }
  659. 六、最远manhattan距离
  660. int query(int rt, int p, int s) //维护每个状态的最大值、最小值。
  661. void getTable(int pos){//每个点有sta个状态
  662. int i, j, t ;
  663. for(i = ; i < sta ; i ++)
  664. {
  665. t = i ;
  666. tmp[i] = ;
  667. for(j = ; j <= k ; j ++)
  668. {
  669. if(t&) tmp[i] += ar[pos].x[j] ;
  670. else tmp[i] -= ar[pos].x[j] ;
  671. t >>= ;
  672. }
  673. }
  674. }
  675. int solve(){
  676. sta = <<k ; //K维平面
  677. build(, , q) ;//将每个点的sta个状态插入树中
  678. cnt = ;
  679. for(i = ; i <= q ; i ++)
  680. {
  681. if(cnt < ){puts("") ;continue ; }
  682. int ans = ;
  683. for(j = ; j < sta ; j ++)
  684. {
  685. mxs = query(, j, ) ; //查询最大值;
  686. mns = query(, j, ) ; //查询最小值;
  687. ans = ans > mxs - mns ? ans : mxs-mns ;
  688. }
  689. printf("%d\n", ans) ;
  690. }
  691. 七、LCA & RMQ & 树状数组
  692. /*****************************LCA*******************************/
  693. struct QNode{
  694. int from, to, next, no ;
  695. }qe[MAXN];
  696. int cnt ;
  697. int qhead[MAXN], pre[MAXN], LCA[MAXN] ;
  698. inline void addQEdge(int a,int b,int c){
  699. qe[++cnt].from = a ;
  700. qe[cnt].to = b ;
  701. qe[cnt].next = qhead[a] ;
  702. qe[cnt].no = c ;
  703. qhead[a] = cnt;
  704. }
  705. int find(int x){
  706. if(x != pre[x]) pre[x]=find(pre[x]);
  707. return pre[x];
  708. }
  709. void tarjan(int u){
  710. int j, v ;
  711. pre[u] = u ;
  712. for(j = qhead[u] ; j != - ; j = qe[j].next)
  713. {
  714. v = qe[j].to;
  715. LCA[qe[j].no] = find(v) ;
  716. }
  717. for(j = head[u] ; j != - ;j = e[j].next)
  718. {
  719. v = e[j].to ;
  720. tarjan(v) ;
  721. pre[v] = u ;
  722. }
  723. }
  724. /*****************************RMQ*******************************/
  725. int mn[MAXN][] ;
  726. void rmq_init(int num){
  727. int i , j ;
  728. for(j = ; j <= num ; j ++ ) mn[j][] = height[j] ;
  729. int m = floor(log((double)num)/log(2.0)) ;
  730. for(i = ; i <= m ; i ++ )
  731. {
  732. for(j = num ; j > ; j -- )
  733. {
  734. mn[j][i] = mn[j][i-] ;
  735. if(j+(<<(i-)) <= num)
  736. mn[j][i] = min( mn[j][i] , mn[j+(<<(i-))][i-]) ;
  737. }
  738. }
  739. }
  740. int rmq(int l,int r){
  741. int m = floor(log((double)(r-l+))/log(2.0)) ;
  742. int a = min(mn[l][m], mn[r-(<<m)+][m] ) ;
  743. return a ;
  744. }
  745. /*****************************树状数组*******************************/
  746. int Lowbit(int t){ //求最小幂2^k
  747. return t&(-t) ;
  748. }
  749. int Sum(int end) { //求前n项和
  750. int sum = ;
  751. while(end > )
  752. {
  753. sum += c[end];
  754. end -= Lowbit(end);
  755. }
  756. return sum;
  757. }
  758. void plus(int pos , int n, int num){ //对某个元素进行加法操作
  759. while(pos <= n)
  760. {
  761. c[pos] += num;
  762. pos += Lowbit(pos);
  763. }
  764. }
  765. 八、划分树
  766. int SU[];
  767. int U[][];
  768. int toL[][];
  769. int n,m,a,b,k,t;
  770. inline int cmp(const void *a,const void *b){return *((int *)a) - *((int *)b) ;}
  771. void buildtree(int l,int r,int d){
  772. int i ;
  773. if (l==r) return;
  774. int mid = (l+r)>> , nowl = l , nowr = mid+ , midtol = ;
  775. for (i = mid ;i>=l && SU[i] == SU[mid] ; i--) ++midtol ;
  776. for (i = l ; i <= r ; i++)
  777. {
  778. toL[d][i] = i==l ? : toL[d][i-];
  779. if (U[d][i] < SU[mid])
  780. {
  781. U[d+][nowl++] = U[d][i];
  782. ++toL[d][i];
  783. }
  784. else if (U[d][i]==SU[mid] && midtol)
  785. {
  786. U[d+][nowl++] = U[d][i];
  787. ++toL[d][i];
  788. --midtol;
  789. }
  790. else U[d+][nowr++] = U[d][i];
  791. }
  792. buildtree(l,mid,d+);
  793. buildtree(mid+,r,d+);
  794. }
  795. int answer(int a,int b,int k){
  796. int l = ,r = n,d = ;
  797. int ls,rs,mid;
  798. while (a != b)
  799. {
  800. ls = a==l ? : toL[d][a-];
  801. rs = toL[d][b];
  802. mid = (l+r)>>;
  803. if (k <= rs - ls)
  804. {
  805. a = l+ls;
  806. b = l+rs-;
  807. r = mid;
  808. }
  809. else {
  810. a = mid++a-l-ls;
  811. b = mid++b-l-rs;
  812. k -= rs-ls;
  813. l = mid+;
  814. }
  815. ++d;
  816. }
  817. return U[d][a];
  818. }
  819. int solve(){
  820. for (i=;i<=n;i++)
  821. {
  822. scanf("%d",&t);
  823. SU[i]=U[][i]=t;
  824. }
  825. sort(SU+, SU++n) ;
  826. buildtree( , n , );
  827. printf("%d\n",answer(a, b, k ) );
  828. }

acm数据结构整理的更多相关文章

  1. ACM数据结构-并查集

    ACM数据结构-并查集   并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合 ...

  2. 转 Python常见数据结构整理

    http://www.cnblogs.com/jeffwongishandsome/archive/2012/08/05/2623660.html Python常见数据结构整理 Python中常见的数 ...

  3. ACM数据结构-树状数组

    模板: int n; int tree[LEN]; int lowbit(int x){ return x&-x; } void update(int i,int d){//index,del ...

  4. ACM数据结构相关资料整理【未完成,待补充】

    在网上总是查不到很系统的练ACM需要学习的数据结构资料,于是参考看过的东西,自己整理了一份. 能力有限,欢迎大家指正补充. 分类主要参考<算法竞赛入门经典训练指南>(刘汝佳),山东大学数据 ...

  5. Java数据结构整理(一)

    ava数据结构内容整理关键字: 数据结构 Collection:List.SetMap:HashMap.HashTable如何在它们之间选择一.Array , ArraysJava所有“存储及随机访问 ...

  6. ACM算法整理(不断补充ing)

    动态规划 1.背包问题 (1)01背包 ,n) DFR(v,V,C[i]) F[v]=max(F[v],F[v-C[i]]+W[i]); } //初始化时 //若背包不一定装满F全初始化为0 //若装 ...

  7. (数据结构整理)NJUPT1054

    这一篇博客以一些OJ上的题目为载体,整理一下数据结构.会陆续的更新. .. 我们都知道,数据结构的灵活应用有时能让简化一些题目的解答. 一.栈的应用 1.NJUPT OJ 1054(回文串的推断) 回 ...

  8. redis数据结构整理(二)

    摘要: 1.各个数据结构的应用举例 1.1 String类型应用举例 1.2List类型应用举例 1.3Set类型应用举例 1.4Sorted Set类型应用举例 1.5Hash类型应用举例 内容: ...

  9. redis数据结构整理(一)

    摘要: 0.redis安装 1.redis的常用数据结构类型 1.1  String 1.2  List 1.3  Set 1.4  Sorted Set 1.5  Hash 2.redis是单进程单 ...

随机推荐

  1. VC中不同类型DLL及区别

    1. DLL的概念可以向程序提供一些函数.变量或类. 静态链接库与动态链接库的区别:(1)静态链接库与动态链接库都是共享代码的方式.静态链接库把最后的指令都包含在最终生成的EXE文件中了:动态链接库不 ...

  2. linux Ubuntu12 设置root用户登录图形界面

    Ubuntu 12.04默认是不允许root登录的,在登录窗口只能看到普通用户和访客登录.以普通身份登陆Ubuntu后我们需要做一些修改,普通用户登录后,修改系统配置文件需要切换到超级用户模式,在终端 ...

  3. 解决ubuntu中vi不能正常使用方向键与退格键的问题

    方案一: 问题: ubuntu中vi在编辑状态下方向键不能用,还有回格键不能删除等我们平时习惯的一些键都不能使用. 解决办法: 可以安装vim full版本,在full版本下键盘正常,安装好后同样使用 ...

  4. Android隐藏输入法键盘(hideSoftInputFromInputMethod没有效果)

    在个别时候,需要强制隐藏Android输入法键盘,如当前键盘正在显示,这个时候点击了侧滑面板,就要强制隐藏输入法键盘.网上常见的方法有: 1. InputMethodManager imm = (In ...

  5. 安装Hadoop系列 — 安装Hadoop

    安装步骤如下: 1)下载hadoop:hadoop-1.0.3     http://archive.apache.org/dist/hadoop/core/hadoop-1.0.3/   2)解压文 ...

  6. js setTimeout深度递归后完成回调

    setTimout原型: iTimerID = window.setTimeout(vCode, iMilliSeconds [, sLanguage])     setTimeout有两种形式 se ...

  7. poj 3009 Curling 2.0( dfs )

    题目:http://poj.org/problem?id=3009 参考博客:http://www.cnblogs.com/LK1994/ #include <iostream> #inc ...

  8. 大四实习准备2_java异常处理_android控件练习

    2015-4-24 Java 异常处理 可以有多个catch;ArrayIndexOutOfBoundsException类是Exception类的子类RuntimeException类的一个间接子类 ...

  9. 中南大学oj 1317 Find the max Link 边权可以为负的树上最长路 树形dp 不能两遍dfs

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1317经典问题:树上最长路,边权可以为负值的,树形dp,不能用两边dfs.反例:5 41 2 22 ...

  10. jquery图片轮播-插件

    更新内容: 1. 页面结构和css样式必定类似下边放置 2. 点击左右按钮,实现左右滑动. 3. 这一般用于多个图片轮播使用,简化并优化代码. 若因不同需求,均可自行将插件scrollimgplus. ...