UVALive - 5902 Movie collection 二叉索引树
2015-04-06 19:31
423 查看
题目大意:有一个人有n个光盘,从下到上依次是n-1,现在给出操作m,意思是要把光盘m拿出来并放到最上面,并问操作前,关盘m上面有多少个光盘
解题思路:用两个数组,pos数组纪录每个数所在的位置,t数组纪录这个数前面有多少个光盘
将第n个放在第一个,第n-1个放在第2个,依此类推,然后更新t数组,这样的话,如果要求编号为m的光盘上面有多少个光盘,就可以直接用sum(maxn-1) - sum(pos[m])
然后,每次更新的时候,先更新pos[m]后面的,依此-1,然后再将pos[m]设置为当前这些光盘的最后面,再更新pos[m]后面的
解题思路:用两个数组,pos数组纪录每个数所在的位置,t数组纪录这个数前面有多少个光盘
将第n个放在第一个,第n-1个放在第2个,依此类推,然后更新t数组,这样的话,如果要求编号为m的光盘上面有多少个光盘,就可以直接用sum(maxn-1) - sum(pos[m])
然后,每次更新的时候,先更新pos[m]后面的,依此-1,然后再将pos[m]设置为当前这些光盘的最后面,再更新pos[m]后面的
[code]#include<cstdio> #include<cstring> const int maxn = 100010 << 2; int t[maxn], pos[maxn], n, m; int lowbit(int x) { return x&(-x); } void Update(int x, int d) { while(x < maxn) { t[x] += d; x += lowbit(x); } } int sum(int x) { int ans = 0; while(x > 0) { ans += t[x]; x -= lowbit(x); } return ans; } void init() { for(int i = 1; i <= n; i++) { Update(i,1); pos[i] = n - i + 1; } } int main() { int test; scanf("%d", &test); while(test--) { scanf("%d%d", &n, &m); memset(t,0,sizeof(t)); init(); int cur = n, x; for(int i = 0; i < m; i++) { scanf("%d", &x); int ans = sum(maxn-1) - sum(pos[x]); printf("%d%c", ans, i == m - 1 ? '\n':' '); Update(pos[x],-1); pos[x] = ++cur; Update(pos[x],1); } } return 0; }
相关文章推荐
- UVALive 5902 Movie collection
- uvalive 5902(BIT)
- UVa 1513 / UVALive 5902 Movie collection (树状数组)
- UVALive 5902 Movie collection(树状数组)
- UVALive 5902 Movie collection
- UVALive - 5902 Movie collection
- UVa 1513 / UVALive 5902 Movie collection (树状数组)
- UvaLive-5902-Movie collection
- UVALive 5902 Movie collection
- UVALive 6525 Attacking rooks 二分匹配 经典题
- UVALive 6533 Inverting Huffman 哈夫曼树(构造
- UVALive6257-剪枝|dp-Chemist's vows
- UVALive - 7503 Change(规律)
- 【暑假】[实用数据结构]UVAlive 3026 Period
- UVALIVE 4287 Proving Equivalences (强连通分量+缩点)
- uvalive 4725(贪心 + 二分)
- UVALive 7512 November 11th(模拟, 思维)
- UVAlive 5792 Diccionário Portuñol (Trie)
- UVALive 6263 The Dragon and the knights --统计,直线分平面
- UVALive 5844 dfs暴力搜索