• <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, 評(píng)論 - 81, 引用 - 0
            數(shù)據(jù)加載中……

            PKU 3145 Harmony Forever

            題目鏈接:http://poj.org/problem?id=3145

            /*
            題意:
                對(duì)于一個(gè)集合S,一共兩種操作:
            1. B X: 添加一個(gè)數(shù)X到S. 第K個(gè)B操作發(fā)生在第K個(gè)時(shí)間點(diǎn),并且每個(gè)之前S集合中沒有X。
            2. A Y: 在S集合中所有數(shù)中, 被Y除后余數(shù)最小的,如果有相同的,選擇最近插入的那個(gè)
            數(shù),如果沒有則輸出-1

            題解:
                樹狀數(shù)組 或者 線段樹

            思路:
                這題主要看怎么去平衡了。如果數(shù)據(jù)量很小,可以直接開一個(gè)一維數(shù)組,下標(biāo)表示除
            數(shù)Y,每次B操作的時(shí)候遍歷一遍該數(shù)組,將答案存下來。但是當(dāng)插入操作很多的時(shí)候這個(gè)
            復(fù)雜度就比較大了,因?yàn)閿?shù)字的范圍是(1 <= X, Y <= 500000),每次都執(zhí)行插入操作,并
            且遍歷整個(gè)數(shù)組進(jìn)行更新的話總的執(zhí)行次數(shù)就是500000^2,于是可以換個(gè)角度,想想其他
            辦法,用每個(gè)數(shù)的值作為樹狀數(shù)組的下標(biāo),每次B操作就將該數(shù)插入到樹狀數(shù)組中,等到A
            操作進(jìn)行詢問時(shí),利用樹狀數(shù)組的成段求和,統(tǒng)計(jì)[0, Y-1]、[Y, 2*Y-1]  這些區(qū)間段
            中最小的sum不為0的數(shù),然后取一個(gè)最小值。這樣的方法當(dāng)Y很大的時(shí)候復(fù)雜度是很小的,
            但是如果Y是1的話就退化成O(n)了。于是我們可以將以上兩種方法結(jié)合一下,Y的值比較小
            的時(shí)候存在數(shù)組中,即使讀取,大的時(shí)候利用樹狀數(shù)組+二分進(jìn)行統(tǒng)計(jì)找出最小值。
                這個(gè)平衡的系數(shù)可以取sqrt(50000),但是關(guān)鍵還是要看題目的數(shù)據(jù),所以如果超時(shí)就
            左右稍作調(diào)整即可。
             
            */

            #include 
            <iostream>

            using namespace std;

            #define mod_split 6208
            #define maxn 500010
            int n;
            int ans[mod_split + 1], tim[ mod_split + 1 ];
            int c[maxn];
            int nt[maxn];

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


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

                
            return ;
            }


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

                
            return s;
            }


            int Bin(int l, int r) {
                
            if(!l) l++;
                
            if(l >= maxn) l = maxn - 1;
                
            if(r >= maxn) r = maxn - 1;

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

                
            return ans;
            }


            int main() {
                
            int i, j;
                
            int Case = 1;
                
            while(scanf("%d"&n) != EOF && n) {
                    
            if(Case != 1)
                        puts(
            "");

                    
            for(j = 0; j <= mod_split; j++{
                        ans[j] 
            = mod_split + 1;
                        tim[j] 
            = -1;
                    }

                    memset(c, 
            0sizeof(c));
                    printf(
            "Case %d:\n", Case ++ );
                    
            int Time = 0;
                    
            for(i = 1; i <= n; i++{
                        
            char str[10];
                        
            int x;
                        scanf(
            "%s %d", str, &x);
                        
            if(str[0== 'B'{
                            Time 
            ++;
                            
            for(j = 1; j <= mod_split; j++{
                                
            int p = x % j;
                                
            if(p <= ans[j]) {
                                    ans[j] 
            = p;
                                    tim[j] 
            = Time;
                                }

                            }

                            add(x);
                            nt[x] 
            = Time;
                        }
            else {
                            
            if(x <= mod_split) {
                                printf(
            "%d\n", tim[x]);
                            }
            else {
                                
            int l = 0, r = x - 1;
                                
            int MinVal = -1;
                                
            int MinTime;
                                
            while(1{
                                    
            int v = Bin(l, r);
                                    
            if(v != -1{
                                        
            int Mod = v % x;
                                        
            if(Mod < MinVal ||  MinVal == -1{
                                            MinVal 
            = Mod;
                                            MinTime 
            = nt[v];
                                        }
            else if(Mod == MinVal) {
                                            
            if(MinTime < nt[v])
                                                MinTime 
            = nt[v];
                                        }

                                    }

                                    
            if(l >= maxn || r >= maxn)
                                        
            break;
                                    l 
            += x;
                                    r 
            += x;
                                }


                                
            if(MinVal != -1)
                                    printf(
            "%d\n", MinTime);
                                
            else
                                    printf(
            "-1\n");
                            }

                        }

                    }


                }

                
            return 0;
            }

            posted on 2011-04-10 11:12 英雄哪里出來 閱讀(2423) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 線段樹樹狀數(shù)組

            久久精品国产亚洲AV香蕉| 久久99久久99精品免视看动漫| 97r久久精品国产99国产精| 国产精品99久久久久久人| 国产免费久久久久久无码| 99久久做夜夜爱天天做精品| 亚洲精品无码久久久久sm| 国产精品va久久久久久久| 亚洲中文字幕久久精品无码APP| 99国产欧美久久久精品蜜芽 | 久久天天躁狠狠躁夜夜不卡| 久久av无码专区亚洲av桃花岛| 热re99久久精品国产99热| 无码人妻久久一区二区三区免费| 国产精品美女久久久网AV| 久久亚洲AV成人出白浆无码国产| 久久se这里只有精品| 国产精品久久久久aaaa| 无码8090精品久久一区 | 久久亚洲欧美日本精品| 亚洲国产一成久久精品国产成人综合| 精品久久久久香蕉网| 久久人做人爽一区二区三区| 亚洲国产精品久久久久| 久久精品草草草| 久久精品国产亚洲AV无码娇色| 久久久久久久波多野结衣高潮| 国产99久久久久久免费看| 国产精品久久久久9999| 国内精品久久久久影院日本| 久久精品国产精品亚洲精品| 婷婷久久综合九色综合九七| 久久精品一区二区影院| 午夜精品久久久久久影视777| 很黄很污的网站久久mimi色| 久久99热这里只有精品国产| 精品久久久久中文字幕一区| 久久综合伊人77777麻豆| 久久夜色撩人精品国产小说| 性做久久久久久久久久久| 国产成人精品综合久久久久|