zoukankan      html  css  js  c++  java
  • Who Gets the Most Candies? POJ

    预备知识:反素数解析

    思路:有了反素数的解法之后就是线段树的事了。

    我们可以用线段树来维护哪些人被淘汰,哪些人没被淘汰,被淘汰的人的位置,没被淘汰的人的位置。

    我们可以把所有人表示为一个[1,n]的区间,没被淘汰的人权值为1,那么通过线段树维护区间和,就可以知道没被淘汰人的分布情况,tree[root].value就是总人数。因为线段树的二分性质,如果淘汰的人在第x个位置,那么我们可以找到区间和为x的位置来得到这个人的位置,把这个位置的权值更新为0,然后更新线段树,就可以表示这个人被淘汰,总人数也是减去1,就可以表示游戏中还剩多少人。

    假设这个被淘汰的人位置是inx,下一个淘汰的人位于他的左(右)第A个,我们可以mod = A%(剩余人数),然后我们可以得到inx左边(L)和右边的人数(R),然后根据mod和A的正负号来确定下一个人的位置。

      1 #include <iostream>
      2 #include <cmath>
      3 #include <cstdio>
      4 
      5 #define ll long long
      6 
      7 using namespace std;
      8 
      9 const int N = 5e5+10;
     10 struct Info{
     11     char name[20];
     12     int turn;
     13 }p[N];
     14 struct node{
     15     int l,r,value;
     16     int mid(){ return (l+r) >> 1; }
     17 }tree[N << 2];
     18 int c[N];
     19 int n, s, ss, inx;
     20 int pr[] = {2,3,5,7,11,13,17,19,23,29};
     21 int Max,num;
     22 
     23 void dfs(int inx, int v, int cnt, int pw){
     24     for(int i = 1; i <= pw; ++i){
     25         if((ll)v * pr[inx] > (ll)n){
     26             if(Max < cnt * i){
     27                 Max = cnt * i;
     28                 num = v;
     29                 
     30             }else if(cnt * i == Max) num = min(num, v);
     31             break;
     32         }
     33         else dfs(inx + 1, v *= pr[inx], cnt * (i + 1), i);
     34 
     35     }
     36 }
     37 
     38 //反素数模板
     39 void AntPrime(){
     40     Max = 1;
     41     dfs(0, 1, 1, 30);   
     42 }
     43 
     44 void build_tree(int rt, int L, int R){
     45     tree[rt].l = L; tree[rt].r = R;
     46     if(L == R){
     47         if(L == s) inx = rt;
     48         tree[rt].value = 1;
     49         return;
     50     }
     51     int mid = tree[rt].mid();
     52     int lson = rt << 1;
     53     int rson = rt << 1 | 1;
     54     build_tree(lson, L, mid);
     55     build_tree(rson,mid + 1, R);
     56     tree[rt].value = tree[lson].value + tree[rson].value;
     57 }
     58 
     59 void update(int x){
     60     while(x != 1){
     61         --tree[x].value;
     62         x >>= 1;
     63     }
     64 }
     65 
     66 void search(int tot,int rt){
     67     //找到位置
     68     if(tree[rt].l == tree[rt].r){
     69         ss = tree[rt].l; //原始队列的位置
     70         inx = rt; //线段树的位置,方便更新
     71         return;
     72     }
     73     int lson = rt << 1;
     74     int rson = rt << 1 | 1;
     75     if(tree[lson].value >= tot) search(tot, lson);
     76     else search(tot - tree[lson].value, rson);
     77 }
     78 
     79 void solve(){
     80     while(~scanf("%d%d", &n, &s)){
     81         build_tree(1,1,n);
     82         AntPrime();//得到反素数和它的约数个数
     83         for(int i = 1; i <= n; ++i){
     84             scanf("%s%d", p[i].name, &p[i].turn);
     85         }
     86         int cnt = 0;
     87         int remain = n;
     88         //s  淘汰队列人的位置
     89         //ss 原始队列人的位置
     90         ss = s;
     91         while(++cnt != num){
     92             update(inx);//更新线段树
     93             int turn = abs((double)p[ss].turn); 
     94             turn %= (remain - 1);
     95             if(!turn) turn = remain - 1;
     96             if(p[ss].turn > 0){ 
     97                 int r = remain - s;
     98                 if(r >= turn) s = s + turn - 1;
     99                 else s = turn - r;
    100             }else{
    101                 int l = s - 1;
    102                 if(l >= turn) s = l - turn + 1;
    103                 else s = (remain - 1) - (turn - l) + 1;
    104             }
    105             // cout << "position is " << ss << endl;
    106             // cout << "jumped out people  " << p[ss].name << endl;
    107             search(s, 1);
    108             --remain;
    109         }
    110         printf("%s %d
    ", p[ss].name, Max);
    111     }    
    112 }
    113 
    114 int main(){
    115 
    116     solve();
    117 
    118     return 0;
    119 }
  • 相关阅读:
    9、 docker容器数据卷
    第十八章 MySQL数据库优化
    第十七章 MySQL的VIP漂移和Atlas
    第十六章 MHA高可用(续)
    第一章 shell基础
    第十五章 MHA高可用
    第十四章 MySQL的各种主从
    第十三章 MySQL的主从复制
    第十二章 MySQL的恢复与备份
    第十一章 MySQL日志详解
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12569041.html
Copyright © 2011-2022 走看看