hrbust 哈理工oj 1752Page Rank【线段树好题】
2016-02-12 15:08
399 查看
Page Rank | ||||||
| ||||||
Description | ||||||
There are n webpages, each of which has its respective page rank. The content is constantly updated and page rank is also constantly changing. Can you immediately find the page with highest weight? Note: We set the page numbers from 1 to n. | ||||||
Input | ||||||
There are multiple test cases, process to the end of file. For each test case: Line 1: This line contains an integer n, indicating the number of pages. Line 2: This line contains n integer, pr1, pr2, pr3, ..., prn, representing the page rank of each page. Line 3: This line contains an integer q, indicating the number of operations. Line 4..q+3: Each line indicating an operation. There are two operation formats: C i pr : change ith page's page rank to pr. Q : query a page with the highest page rank, output the page's number and its page rank. Limits 1<=n<=100,000 1<=q<=200,000 0<=pr<=1,000,000,000 | ||||||
Output | ||||||
For each case: Each "Q" query outputs a line containing the page number and page rank of the page of the highest page rank. If there is more than one page which has the highest page rank, output the page with largest number. After each test case, output a blank line. | ||||||
Sample Input | ||||||
5 30 9 0 20 5 6 C 1 19 C 3 22 C 3 4 Q C 4 12 Q 5 13 10 20 7 7 7 C 4 22 C 4 21 C 4 11 C 3 10 C 5 15 C 2 17 Q | ||||||
Sample Output | ||||||
4 20 1 19 2 17 |
首先是build:
void pushup(int rt)
{
if (tree[rt<<1] > tree[rt<<1|1])//位子跟着值的变化而变化,这里也可以写成结构体,看起来方便一点。
{
tree[rt] = tree[rt<<1];
posn[rt] = posn[rt<<1];
}
else
{
tree[rt] = tree[rt<<1|1];
posn[rt] = posn[rt<<1|1];
}
}
void build(int l, int r, int rt)//大同小异的部分,
{
if (l == r)
{
scanf("%d", &tree[rt]);
posn[rt] = l;
}
else
{
int m = (l + r) >> 1;
build(lson);
build(rson);
pushup(rt);
}
}然后是update、
void update(int p, int val, int l, int r, int rt)
{
if (l == r)
{
tree[rt] = val;
}
else
{
int m = (l + r) >> 1;
if (p <= m)
{
update(p, val, lson);
}
else
{
update(p, val, rson);
}
pushup(rt);
}
}关键部分是query操作:
int query(int L, int R, int l, int r, int rt, int *pos)
{
if (L <= l && r <= R)//区间
{
*pos = posn[rt];
return tree[rt];
}
else
{
int m = (l + r) >> 1;
int ret1 = INT_MIN;
int ret2 = INT_MIN;
int pa, pb;
int *pos1 = &pa;
int *pos2 = &pb;
if (L <= m)
{
ret1 = query(L, R, lson, pos1);//ret1表示这部分区间的最大值,同时在这部分的query过程中,找到了pos1,表示这部分区间最大值的位子
}
if (R > m)
{
ret2 = query(L, R, rson, pos2);//ret2表示这部分区间的最大值,
}
if (ret1 > ret2)//如果ret1>ret2,无疑让pos变成pa
{
*pos = pa;
}
else//这里是关键,题目中说,如果有值相同的情况下,要输出大的位子、我们知道,rson的number总是比lson的number大,所以这里保证了题目的要求。
{
*pos = pb;
ret1 = ret2;
}
return ret1;//return最大值、
}
}
最后上完整的AC代码:
#include<cstdio> #include<climits> #include<algorithm> using namespace std; #define lson l, m, rt<<1 #define rson m+1, r, (rt<<1)|1 int tree[111111<<2]; int posn[111111<<2]; void pushup(int rt) { if (tree[rt<<1] > tree[rt<<1|1]) { tree[rt] = tree[rt<<1]; posn[rt] = posn[rt<<1]; } else { tree[rt] = tree[rt<<1|1]; posn[rt] = posn[rt<<1|1]; } } void build(int l, int r, int rt) { if (l == r) { scanf("%d", &tree[rt]); posn[rt] = l; } else { int m = (l + r) >> 1; build(lson); build(rson); pushup(rt); } } void update(int p, int val, int l, int r, int rt) { if (l == r) { tree[rt] = val; } else { int m = (l + r) >> 1; if (p <= m) { update(p, val, lson); } else { update(p, val, rson); } pushup(rt); } } int query(int L, int R, int l, int r, int rt, int *pos) { if (L <= l && r <= R) { *pos = posn[rt]; return tree[rt]; } else { int m = (l + r) >> 1; int ret1 = INT_MIN; int ret2 = INT_MIN; int pa, pb; int *pos1 = &pa; int *pos2 = &pb; if (L <= m) { ret1 = query(L, R, lson, pos1); } if (R > m) { ret2 = query(L, R, rson, pos2); } if (ret1 > ret2) { *pos = pa; } else//这里保证最大位子优先、 { *pos = pb; ret1 = ret2; } return ret1; } } int main(void) { int n, m; while (scanf("%d", &n) != EOF) { build(1, n, 1); scanf("%d", &m); char op[2]; int a, b; while (m--) { scanf("%s", op); if (op[0] == 'Q') { int pos; printf("%d %d\n", pos, query(1, n, 1, n, 1, &pos)); } else { scanf("%d%d", &a, &b); update(a, b, 1, n, 1); } } printf("\n"); } return 0; }
相关文章推荐
- 01背包的学习
- 方法的重载
- 用i个点组成高度为不超过j的二叉树的数量。
- 写给五年后的自己2021
- HDU-1010-Tempter of the Bone( DFS + 深度优先搜索 )
- Temporary Post Used For Theme Detection (387b0fac-cc76-4eb9-8534-75ac8425eec1 - 3bfe001a-32de-4114-a6b4-4005b770f6d7)
- android中view控件的setTag()和getTag()用法和功能介绍
- JSF导出excel文件文件名使用中文,支持linux
- Educational Codeforces Round 7 E. Ants in Leaves 贪心
- 类名引用static变量好处
- List集合去重的一种方法 z
- JVM体系结构
- JQuery——插件的开发和使用(一)
- Volley学习记录(三)
- 可以输入的下拉框,可以筛选内容,可输入筛选下拉框(原创)
- IntelliJ IDEA 16 EAP新特性一览
- java字符操作获取汉字的拼音以及其它经常使用工具
- POJ 2632 Crashing Robots(简单模拟)
- Java学习笔记4-反射
- 插入排序