• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 97, 文章 - 22, 評論 - 81, 引用 - 0
            數(shù)據(jù)加載中……

            PKU 2886 Who Gets the Most Candies

            題目鏈接:http://poj.org/problem?id=2886
            /*
            題意:
                有一排編號為1到N的小孩順時針圍成圈,沒人手上有一張編號為A[i]的卡
            片,游戲從第K個小孩開始,他告訴自己的卡片數(shù)字然后跳出圓圈,如果A[i]
            大于0,那么左數(shù)第A[i]個小孩出圈否則右數(shù)第A[i]個出圈,游戲一直進行直到
            所有孩子都出去位置,第p個出圈的將會得到F(p)的糖果,F(xiàn)(p)表示p的因子數(shù)
            ,問誰拿到了最多的糖果。

            解法:
                樹狀數(shù)組 + 數(shù)論

            思路:
                直接模擬整個過程的復雜度是O(n^2),但是n非常大,所以必須優(yōu)化,我們
            發(fā)現(xiàn)模擬的時候瓶頸在于每次找到下一個小孩的時候需要遍歷全部,所以如果把
            這一步簡化,問題就會簡單許多,利用樹狀數(shù)組的成段求和就可以做到每次找下
            一個小孩的復雜度降為log(n),我們將每個孩子對應到樹狀數(shù)組的下標,如果當
            前小孩存在那么就記為1,不存在記為0。這樣,統(tǒng)計第x到第y個孩子中間有多少
            個孩子就可以直接采用樹狀數(shù)組的sum(y) - sum(x-1)來完成,那么問題就轉化成
            了如何在第x到第y個孩子中間找到第k個尚存在的孩子,于是只要二分這個k,然
            后利用成段求和來判可行。這樣總的復雜度就可以降到O(nlognlogn)了。
                還有一個常數(shù)優(yōu)化,就是算每個孩子的因子數(shù)可以在篩選素數(shù)的時候一起做掉
            ,然后用一個數(shù)組保存1到n的因子最大值的id,這樣就不用每次都重新算過了。而
            且查找第k個孩子只要做到第id個就可以退出循環(huán)(原本是要做n次的)。
            */


            #include 
            <iostream>

            using namespace std;

            #define maxn 500010

            int lowbit(int x) {
                
            return x & (-x);
            }


            int n;
            int c[maxn];

            void add(int pos, int v) {
                
            while(pos <= n) {
                    c[pos] 
            += v;
                    pos 
            += lowbit(pos);
                }

            }


            int sum(int pos) {
                
            int s = 0;
                
            while(pos > 0{
                    s 
            += c[pos];
                    pos 
            -= lowbit(pos);
                }

                
            return s;
            }


            bool f[maxn];
            int prime[maxn], ans[maxn], size;
            int MaxAns[maxn], id[maxn];

            struct Point {
                
            string name;
                
            int val;
            }
            pt[maxn];


            // 從x到y(tǒng)中找到第k個存在的元素
            int Binary(int l, int r, int k) {
                
            int ans;
                
            if(l <= r) {
                    
            int pre = sum(l-1);
                    
            while(l <= r) {
                        
            int m = (l + r) >> 1;
                        
            if(sum(m) - pre >= k) {
                            r 
            = m - 1;
                            ans 
            = m;
                        }
            else
                            l 
            = m + 1;
                    }

                    
            return ans;
                }

                swap(l, r);
                
            int pre = sum(r);
                
            while(l <= r) {
                    
            int m = (l + r) >> 1;
                    
            if(pre - sum(m-1>= k) {
                        l 
            = m + 1;
                        ans 
            = m;
                    }
            else
                        r 
            = m - 1;
                }

                
            return ans;
            }


            int main() {
                
            int i, j;
                
            for(i = 2; i < maxn; i++{
                    
            if(!f[i]) {
                        prime[size
            ++= i;
                        ans[i] 
            = 2;
                        
            for(j = i+i; j < maxn; j += i) {
                            
            int v = j;
                            
            if(!ans[j]) ans[j] = 1;
                            
            int x = 1;
                            
            while(v % i == 0{
                                v 
            /= i;
                                x 
            ++;
                            }

                            ans[j] 
            *= x;

                            f[j] 
            = 1;
                        }

                    }

                }


                MaxAns[
            1= 1;
                id[
            1= 1;
                
            for(i = 2; i < maxn; i++{
                    MaxAns[i] 
            = MaxAns[i-1];
                    id[i] 
            = id[i-1];

                    
            if(ans[i] > MaxAns[i]) {
                        MaxAns[i] 
            = ans[i];
                        id[i] 
            = i;
                    }

                }

                
            int k;
                
            while(scanf("%d %d"&n, &k) != EOF) {
                    
            int pos = id[n];

                    
            for(i = 1; i <= n; i++{
                        
            char str[20];
                        
            int v;
                        scanf(
            "%s %d", str, &v);
                        pt[i].name 
            = str;
                        pt[i].val 
            = v;
                    }


                    
            if(MaxAns[pos] == 1{
                        printf(
            "%s 1\n", pt[k].name.c_str());
                        
            continue;
                    }



                    
            for(i = 1; i <= n; i++{
                        c[i] 
            = 0;
                    }

                    
            for(i = 1; i <= n; i++{
                        add(i, 
            1);
                    }


                    
            int nowChild = k;
                    
            int nCount = 1;    
                    add(k, 
            -1);
                    
                    
            while(nCount < pos) {
                        
            int A = pt[ nowChild ].val;
                        
            if(A > 0{
                            A 
            %= (n - nCount);
                            
            if(A == 0)
                                A 
            = n - nCount;

                            
            int big = sum(n) - sum(nowChild);
                            
            if(A <= big) {
                                nowChild 
            = Binary(nowChild+1, n, A);
                            }
            else {
                                A 
            -= big;
                                nowChild 
            = Binary(1, nowChild-1, A);
                            }

                        }
            else {    
                            A 
            = -A;
                            A 
            %= (n - nCount);
                            
            if(A == 0{
                                A 
            = n - nCount;
                            }


                            
            int les = sum(nowChild - 1);
                            
            if(A <= les) {
                                nowChild 
            = Binary(nowChild-11, A);
                            }
            else {
                                A 
            -= les;
                                nowChild 
            = Binary(n, nowChild+1, A);
                            }

                        }
                                
                        add(nowChild, 
            -1);
                        nCount 
            ++;
                    }

                    printf(
            "%s %d\n", pt[nowChild].name.c_str(), MaxAns[pos]);
                }


            }

            posted on 2011-04-07 11:03 英雄哪里出來 閱讀(1237) 評論(0)  編輯 收藏 引用 所屬分類: 樹狀數(shù)組

            精品熟女少妇aⅴ免费久久| 久久人人爽人人爽人人片AV高清 | 久久婷婷午色综合夜啪| 老男人久久青草av高清| 久久精品国产影库免费看| 久久亚洲2019中文字幕| 狠狠色婷婷久久一区二区三区| 91久久精品国产成人久久| 中文字幕无码久久精品青草 | 久久综合给合久久国产免费| 久久精品嫩草影院| 亚洲精品蜜桃久久久久久| 久久久99精品一区二区| 国产成人久久精品激情| 久久99这里只有精品国产| 国产精品欧美久久久久无广告| 亚洲午夜久久久久久久久久| 久久精品国产只有精品66| 国产精品美女久久久| 精品多毛少妇人妻AV免费久久| 国产L精品国产亚洲区久久| 亚洲国产精品无码久久98| 色婷婷久久久SWAG精品| 99久久99久久精品国产片| .精品久久久麻豆国产精品| 精品久久久久久国产| 久久国产AVJUST麻豆| 日本亚洲色大成网站WWW久久| 97久久精品人人澡人人爽| 国产国产成人精品久久| 看久久久久久a级毛片| 无码专区久久综合久中文字幕| 亚洲精品97久久中文字幕无码| 久久天天躁狠狠躁夜夜av浪潮| 久久se这里只有精品| 久久高潮一级毛片免费| 91精品国产高清久久久久久91 | 久久久亚洲AV波多野结衣| 香蕉久久久久久狠狠色| 久久精品极品盛宴观看| 国产精品一区二区久久精品涩爱|