zoukankan      html  css  js  c++  java
  • 线段树题集

    Who Gets the Most Candies?

     POJ - 2886 

    反素数 + 线段树

    题意:有n个人围成一圈,游戏的起点是k,每个人持有一个数字(非编号)num,每次当前的人退出圈,下一个人是他左边的第num个(也就是说下一个退出的是k+num, k可以为负数,表示右边的第num个), 现在一直如果一个人是第i个推出的,那么他的得分就是i的因数的个数,球得分最高的那个人的编号

    题解:先求出小于等于n的里面所有的数字里面应该获得最高分的那个出圈id,按照区间人数建立线段树,依次出圈

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<string.h>
    #include<vector>
    #include<deque>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f3f3f3f3f
    #define inf 0x3f3f3f3f
    #define eps 1e-4
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl;
    
    #define Mod(a,b) a<b?a:a%b+b
    typedef long long LL;
    typedef long long ll;
    const int maxn = 5e5 + 5;
    
    int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
    
    int ans,n;
    int best;
    
    void dfs(int dept,int tmp,int num) {
        //到叶子结点,返回
        if (dept >= 16) return;
        //num记录的因子个数,如果遇到更小的,就更新
        if (num > best) {
            best = num;
            ans = tmp;
        }
        //当因子个数相同时,取值最小的
        if (num == best && ans > tmp) ans = tmp;
        for (int i = 1; i <= 63; i++) {
            if (n / p[dept] < tmp) break;
            dfs(dept + 1, tmp *= p[dept], num * (i + 1));
        }
    }
    
    int a[maxn],num[maxn],st[maxn << 2];
    char name[maxn][20];
    void build(int o, int l, int r) {
        if(l == r) st[o] = a[l];
        else {
            int mid = (l + r) >> 1;
            build(o << 1, l, mid);
            build(o << 1 | 1, mid + 1, r);
            st[o] = st[o << 1] + st[o << 1 | 1];
        }
    }
    
    
    
    int query(int pos,int o,int l,int r) {
        st[o]--;
        if(l == r) return l;
        int mid = (l + r) >> 1;
        int ans;
        if (st[o << 1] >= pos) ans = query(pos,o << 1, l, mid);
        else {
            pos -= st[o << 1];
            ans = query(pos, o << 1 | 1, mid + 1, r);
        }
        return ans;
    }
    int solve(int x) {
        int tmp = (int)sqrt(x * 1.0),ans = 0;
        for(int i = 1; i <= tmp; i++) {
            if (x % i == 0 && i != x / i) {
                ans += 2;
            } else if(x % i == 0)
                ans += 1;
        }
        return ans;
    }
    int main() {
        int k;
        while (~scanf("%d %d", &n, &k)) {
            ans = INF;
            best = 0;
            dfs(0, 1, 1);
            for (int i = 1; i <= n; i++) {
                scanf("%s %d",name[i], &num[i]);
                a[i] = 1;
            }
            build(1, 1, n);
            int ret;
            for (int i = 1; i <= ans; i++) {
                int pos = k;
                ret = query(pos, 1, 1, n);
                pos = num[ret];
    
                if(st[1] == 0) break;
                if(pos > 0) pos = ((k - 2 + st[1]) % st[1] + pos) % st[1] + 1;
                else pos = ((k + pos - 1) % st[1] + st[1]) % st[1] + 1;
                k = pos;
            }
            printf("%s %d
    ",name[ret],solve(ans));
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    一句话解释c#中的特性,你了解多少
    CentOS虚拟机如何设置共享文件夹,并在Windows下映射网络驱动器?
    samba服务器配置及window网络磁盘映射
    PHP中各种Hash算法性能比较
    Redis持久化
    设置redis主从出现的问题
    Redis启动多端口、运行多实例
    Redis学习手册(主从复制)
    tengine/nginx-tomcat动静分离遇到的问题
    使用 Git Hooks 实现自动项目部署
  • 原文地址:https://www.cnblogs.com/smallhester/p/11469521.html
Copyright © 2011-2022 走看看