线段树(单点更新) POJ 2886 Who Gets the Most Candies?

题目传送门

 1 #include <cstdio>
 2 #include <cstring>
 3 #define lson l, m, rt << 1
 4 #define rson m+1, r, rt << 1 | 1
 5
 6 const int MAX_N = 500000 + 10;
 7 int sum[MAX_N << 2];
 8 struct node
 9 {
10     char name[15];
11     int val;
12 }boy[MAX_N<<2];
13 int ans[MAX_N];
14 int id;
15 int n, k;
16
17 void build(int l, int r, int rt)
18 {
19     sum[rt] = r - l + 1;
20     if (l == r)
21         return ;
22     int m = (l + r) >> 1;
23     build (lson);
24     build (rson);
25 }
26
27 int update(int p, int l, int r, int rt)
28 {
29     sum[rt]--;
30     if (l == r)
31     {
32         return l;
33     }
34     int m = (l + r) >> 1;
35     if (p <= sum[rt<<1])
36     {
37         return update (p, lson);
38     }
39     else
40     {
41         return update (p - sum[rt<<1], rson);
42     }
43 }
44
45 void Solve(){   //计算ans
46     memset(ans,0,sizeof(ans));
47     for(int i=1;i<=n;i++){
48         ans[i]++;
49         for(int j=2*i;j<=n;j+=i)
50             ans[j]++;
51     }
52     int max=ans[1];
53     id=1;
54     for(int i=2;i<=n;i++)   //找出第几个人跳出获得的糖最多
55         if(ans[i]>max){
56             max=ans[i];
57             id=i;
58         }
59 }
60
61 int main(void)      //POJ 2886 Who Gets the Most Candies?
62 {
63     //freopen ("inF.txt", "r", stdin);
64
65     while (~scanf ("%d%d", &n, &k))
66     {
67         build (1, n, 1);
68         for (int i=1; i<=n; ++i)
69         {
70             scanf ("%s%d", &boy[i].name, &boy[i].val);
71             //printf ("%s%d\n", boy[i].name, boy[i].val);
72         }
73         Solve();
74         //int maxn = f(n);
75         int mod = sum[1];
76         boy[0].val = 0;
77         int pos = 0;
78         //printf ("%d\n", id);
79         int m=id;
80         while (m--)
81         {
82             if (boy[pos].val > 0)
83                 k=((k-1+boy[pos].val-1)%mod+mod)%mod+1;
84             else
85                 k=((k-1+boy[pos].val)%mod+mod)%mod+1;
86             pos = update (k, 1, n, 1);
87             //printf ("%d ", pos);
88             mod = sum[1];
89         }
90         printf ("%s %d\n", boy[pos].name, ans[id]);
91     }
92 }
时间: 2024-08-01 10:41:03

线段树(单点更新) POJ 2886 Who Gets the Most Candies?的相关文章

线段树(单点更新) POJ 2828 Buy tickets

题目传送门 1 /* 2 结点存储下面有几个空位 3 每次从根结点往下找找到该插入的位置, 4 同时更新每个节点的值 5 */ 6 #include <cstdio> 7 #define lson l, m, rt << 1 8 #define rson m+1, r, rt << 1 | 1 9 10 const int MAX_N = 200000 + 10; 11 int pos[MAX_N], val[MAX_N]; 12 int sum[MAX_N <&

POJ训练计划2828_Buy Tickets(线段树/单点更新)

解题报告 题意: 插队完的顺序. 思路: 倒着处理数据,第i个人占据第j=pos[i]+1个的空位. 线段树维护区间空位信息. #include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node { int x,v; } num[201000]; int sum[1000000],ans[201000]; void cbtree(int rt,int l,in

POJ训练计划2299_Ultra-QuickSort(线段树/单点更新)

解题报告 题意: 求逆序数. 思路: 线段树离散化处理. #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #define LL long long using namespace std; LL sum[2001000],num[501000],_hash[501000]; void push_up(int rt) { sum[rt]=sum[rt*2

POJ 1804 Brainman(5种解法,好题,【暴力】,【归并排序】,【线段树单点更新】,【树状数组】,【平衡树】)

Brainman Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10575   Accepted: 5489 Description BackgroundRaymond Babbitt drives his brother Charlie mad. Recently Raymond counted 246 toothpicks spilled all over the floor in an instant just b

POJ 2828 Buy Tickets (线段树 单点更新 变形)

题目链接 题意:有N个人排队,给出各个人想插队的位置和标识,要求输出最后的序列. 分析:因为之前的序列会因为插队而变化,如果直接算时间复杂度很高,所以可以用 线段树逆序插入,把序列都插到最后一层,len记录该区间里还剩余多少位置,插入的时候就插到剩余的第几个位置, 比如1,2已经插入了,如果再想插入第3个位置,则实际上插入的是5. 因为是逆序的,所以在3之前除了现在的1,2 还有之前的1,2. 1 #include <iostream> 2 #include <cstdio> 3

Buy Tickets+POJ+线段树单点更新的灵活运用

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 12927   Accepted: 6410 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The Lunar New Year wa

poj-----(2828)Buy Tickets(线段树单点更新)

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 12930   Accepted: 6412 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue… The Lunar New Year wa

HDU2852_KiKi&#39;s K-Number(线段树/单点更新)

解题报告 题目传送门 题意: 意思很好理解. 思路: 每次操作是100000次,数据大小100000,又是多组输入.普通模拟肯定不行. 线段树结点记录区间里存在数字的个数,加点删点操作就让该点个数+1,判断x存在就查询[1,x]区间的个数和[1,x-1]的个数. 求x之后第k大的数就先确定小于x的个数t,第t+k小的数就是要求的. #include <iostream> #include <cstdio> #include <cstring> using namespa

POJ3264_Balanced Lineup(线段树/单点更新)

解题报告 题意: 求区间内最大值和最小值的差值. 思路: 裸线段树,我的线段树第一发.区间最值. #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 #define LL long long using namespace std; LL minn[201000],maxx[201000]; void update(LL root,LL l,LL r,LL p,LL