zoukankan      html  css  js  c++  java
  • POJ 2886 Who Gets the Most Candies? 反素数+线段树

    题意:变形的约瑟夫环模型,每个人有一个数字a,从第K个人开始出列,如果数字是正的,就往后数a个人出列,如果书负数,就往反方向数。

    然后用最基本的线段树处理约瑟夫环的方法即可

    但是题目要求的是第x个出列的人的名字,x为1-N中约数最多的数中的最小的那个。这里需要求反素数,即不大于N约数最多的。

    写起来比较多,容易写错,一开始连素数打表都写作了QAQ

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <map>
    #include <set>
    #include <vector>
    #include <string>
    #include <queue>
    #include <stack>
    #include <climits>
    
    using namespace std;
    
    typedef long long LL;
    
    const int maxn = 500000 + 5;
    int sum[maxn << 2];
    
    //线段树
    
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    void build(int rt,int l,int r) {
        if(l == r) sum[rt] = 1;
        else {
            int mid = (l + r) >> 1;
            build(lson); build(rson);
            sum[rt] = sum[rt<<1] + sum[rt<<1|1];
        }
    }
    
    void update(int rt,int l,int r,int tar,int x) {
        if(l == r) sum[rt] = x;
        else {
            int mid = (l + r) >> 1;
            if(tar <= mid) update(lson,tar,x);
            else update(rson,tar,x);
            sum[rt] = sum[rt<<1] + sum[rt<<1|1];
        }
    }
    
    int query(int rt,int l,int r,int v) {
        if(l == r) return l;
        else {
            int mid = (l + r) >> 1,lc = rt<<1,rc = lc + 1;
            if(sum[lc] >= v) return query(lson,v);
            else return query(rson,v - sum[lc]);
        }
    }
    
    //反素数生成
    int prime[20] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};
    int minv[maxn],times[40];
    void dfs(LL arr,int nowcnt,int nowt,LL lim) {
        if(arr > lim) return;
        //cout << arr << " " << nowcnt << " " << nowt << " " << lim << endl;
        minv[nowcnt] = min(minv[nowcnt],(int)arr);
        for(int i = 1;nowt == 0 || i <= times[nowt - 1];i++) {
            arr *= prime[nowt];
            if(arr > lim) break;
            nowcnt = nowcnt / i * (i + 1);
            times[nowt] = i;
            dfs(arr,nowcnt,nowt + 1,lim);
        }
    }
    
    char name[maxn][20];
    int k[maxn],N,K;
    
    void solve() {
        int nowpos = K,ans,ansv,nowk,pos = K;
        build(1,1,N);
        for(int i = 1;i <= N;i++)
            if(minv[i] <= N) ansv = i;
        for(int i = 1;i <= N;i++) {
            pos = query(1,1,N,nowpos);
            update(1,1,N,pos,0);
      //      printf("%d:%s out in %d
    ",pos,name[pos],i);
            nowk = k[pos];
            if(i == minv[ansv]) {
                ans = pos; break;
            }
            if(nowk > 0) nowpos = ((nowpos + nowk - 2) % (N - i) + (N - i)) % (N - i) + 1;
            else nowpos = ((nowpos + nowk - 1) % (N - i) + (N - i)) % (N - i) + 1;
        }
        printf("%s %d
    ",name[ans],ansv);
    }
    
    void setfile() {
        freopen("in.txt","r",stdin);
        freopen("a.txt","w",stdout);
    }
    
    int main() {
    //    setfile();
        for(int i = 1;i <= maxn;i++) minv[i] = INT_MAX;
        dfs(1,1,0,maxn);
        while(scanf("%d%d",&N,&K) != EOF) {
            for(int i = 1;i <= N;i++) scanf("%s%d",name[i],&k[i]);
            solve();
        }
        return 0;
    }

      

  • 相关阅读:
    HTML DOM Body vLink 属性
    HTML <dialog> 标签
    JavaScript atan() 方法
    HTML URL 编码参考手册
    HTML DOM dir 属性
    CSS3 小黄人案例
    CSS 之 圣杯布局&双飞翼布局
    CSS3 渐变
    浏览器前缀
    CSS3 弹性盒布局
  • 原文地址:https://www.cnblogs.com/rolight/p/3841634.html
Copyright © 2011-2022 走看看