• <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>

            The Fourth Dimension Space

            枯葉北風寒,忽然年以殘,念往昔,語默心酸。二十光陰無一物,韶光賤,寐難安; 不畏形影單,道途阻且慢,哪曲折,如渡飛湍。斬浪劈波酬壯志,同把酒,共言歡! -如夢令

            關于浙大月賽B題 快速尋找第k小數...

            這個題我是用線段樹來做的,結果居然是超時。。。后來foreverlin同學告訴我他用樹狀數組過的,但我記得樹狀數組能解決的問題,線段樹一定能解決,而且線段樹的復雜度是logL級別,為什么我會超時呢?還請各位大牛指點。。。
            我的代碼如下:

            #include<iostream>
            #include
            <cstdio>
            #include
            <cstring>
            #include
            <cmath>
            using namespace std;
            #define MAX 300001
            int a[MAX];


            struct node
            {
                
                
            int left;
                
            int right;
                
            int level;
                
            int cnt;
                node 
            *lchild;
                node 
            *rchild;
            }
            dotset[MAX];
            int cou;
            node 
            *Newnode()
            {
                
                node 
            *p=&dotset[cou];
                cou
            ++;
                p
            ->level=0;
                p
            ->cnt=0;
                p
            ->left=0;
                p
            ->right=0;
                p
            ->lchild=NULL;
                p
            ->rchild=NULL;
                
            return p;
            }



            void Build(node *&tree,int left,int right)
            {
                tree
            =Newnode();
                tree
            ->left=left;
                tree
            ->right=right;
                
            if(left==right)
                
            {
                    
            return;
                }

                
            int mid=(left+right)>>1;
                Build(tree
            ->lchild,left,mid);
                Build(tree
            ->rchild,mid+1,right);
            }

            int p=1;
            void Insert(node *tree,int k,int num)
            {
                tree
            ->cnt+=num;
                
            if(tree->left==tree->right)
                
            {
                    tree
            ->level=p;
                    p
            ++;
                    
            return;
                }

                
            int mid=(tree->left+tree->right)>>1;
                
            if(k>mid)
                    Insert(tree
            ->rchild,k,num);
                
            else
                    Insert(tree
            ->lchild,k,num);
            }

            void Insert2(node *tree,int k,int num)
            {
                tree
            ->cnt-=a[k];
                tree
            ->cnt+=num;
                
            if(tree->left==tree->right)
                
            {
                    
            return;
                }

                
            if(k>(tree->left+tree->right)>>1)
                    Insert2(tree
            ->rchild,k,num);
                
            else
                    Insert2(tree
            ->lchild,k,num);
            }


            int Query(node *tree,int k)
            {
                
            if(tree->left==tree->right)
                    
            return tree->level;
                
            int t=tree->lchild->cnt;
                
            if(k<=t)
                    Query(tree
            ->lchild,k);
                
            else 
                    Query(tree
            ->rchild,k-t);
            }



            int main()
            {

                
            int n;
                
            int q;
                node 
            *root;
                
            while(scanf("%d",&n)!=EOF)
                
            {
                    cou
            =0;
                    Build(root,
            1,n);
                    p
            =1;
                    
            int i;
                    
            for(i=1;i<=n;i++)
                    
            {
                        
            int t;
                        scanf(
            "%d",&a[i]);
                        Insert(root,i,a[i]);
                    }

                    scanf(
            "%d",&q);
                    
            for(i=1;i<=q;i++)
                    
            {
                        
            int t;
                        
            char s;
                        cin.ignore();
                        scanf(
            "%c",&s);
                        
            if(s=='q')
                        
            {
                            scanf(
            "%d",&t);
                            printf(
            "%d\n",Query(root,t));
                        }

                        
            else if(s=='p')
                        
            {
                            
            int a1,b1;
                            scanf(
            "%d%d",&a1,&b1);
                            Insert2(root,a1,b1);
                            a[a1]
            =b1;
                        }




                    }

                    
                }

                
            return 0;
            }

            順便發幾句牢騷,為啥我做浙大的題總是不順呢(當然其實我也是第二次做浙大的比賽)。。。浙大好像總喜歡出極限數據,即使算法對了,也不讓我們快速地通過,總是要優化到最佳才行。這樣做好處是比賽的時候實力會更過硬一些吧,畢竟可以說 我們連浙大那么BT的數據都過了,算法肯定是最好的了。。。下次提前做好心理準備吧。。。

            下午花了一個小時 終于弄懂了樹狀數組,總算把這題過了,感覺樹狀數組實現起來比線段樹容易得多,效率也高得多,非常實用。
            #include<iostream>
            #include
            <cmath>
            #include
            <algorithm>
            #include
            <cstring>
            using namespace std;

            int n,q;
            int a[100001],c[100001];

            int lowbit(int k)
            {
                
            return k&(k^(k-1));
            }


            void update(int x,int num)
            {
                
            while(x<=n)
                
            {
                    c[x]
            +=num;
                    x
            +=lowbit(x);     
                }
             
            }
                
            int query(int x)
            {
                
            int sum=0;
                
            while(x>0)
                
            {
                    sum
            +=c[x];
                    x
            -=lowbit(x);    
                }

                
            return sum;      
            }


            int find(int t)
            {

                
            int l=1;
                
            int r=n;
                
            int min;
                
                
            while(l<r)
                
            {
                    
            int mid=(l+r)>>1;
                    
            if(query(mid)>=t&&query(mid-1)<t)
                        
            return mid;
                    
            else if(query(mid)>=t)
                        r
            =mid-1;
                    
            else 
                        l
            =mid+1;
                }

                
            return r;//剛好為最后一個查找點
            }



            int main()
            {
                
            int i,j;
                
            int t;
                
            char s[2];
                
            while(scanf("%d",&n)!=EOF)
                
            {

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

                        scanf(
            "%d",&a[i]);
                        update(i,a[i]);
                    }

                    scanf(
            "%d",&q);
                    
            while(q--)
                    
            {
                        scanf(
            "%s",s);
                        
            if(s[0]=='q')
                        
            {

                            scanf(
            "%d",&t);
                            printf(
            "%d\n",find(t));
                        }

                        
            else 
                        
            {
                            
            int t1,t2;
                            scanf(
            "%d%d",&t1,&t2);
                            update(t1,
            -a[t1]);
                            a[t1]
            =t2;
                            update(t1,a[t1]);
                        }


                    }

                    
                }

                
            return 0;
            }



            posted on 2009-12-15 00:36 abilitytao 閱讀(1825) 評論(7)  編輯 收藏 引用

            評論

            # re: 關于浙大月賽B題 快速尋找第k小數... 2009-12-17 11:19 diwayou

            我有個問題納悶,你用了一堆的C++頭文件,程序里用的全是C的函數,why  回復  更多評論   

            # re: 關于浙大月賽B題 快速尋找第k小數... 2009-12-17 12:40 abilitytao

            @diwayou
            我用的就是C的 --!  回復  更多評論   

            # re: 關于浙大月賽B題 快速尋找第k小數... 2009-12-17 17:00 wxq

            你整的太復雜了...沒那個必要!  回復  更多評論   

            # re: 關于浙大月賽B題 快速尋找第k小數... 2009-12-21 00:26 abilitytao

            @wxq
            請問有什么更好的方法嗎?請指教:-)  回復  更多評論   

            # re: 關于浙大月賽B題 快速尋找第k小數... 2009-12-27 23:41 MasterLuo

            樹狀數組與線段樹應該都是可以過的。不過可以用樹狀數組的地方就沒必要用線段樹了。  回復  更多評論   

            # re: 關于浙大月賽B題 快速尋找第k小數... 2011-05-03 17:54 seeyou

            呃~~能寫點注釋么?這樣看不明白呀,謝謝啦  回復  更多評論   

            久久九九有精品国产23百花影院| 久久青青国产| 久久精品国产精品亚洲精品| 人人狠狠综合久久亚洲婷婷| 久久亚洲中文字幕精品一区四 | 久久久综合九色合综国产| 国产精品久久久久久一区二区三区| 精品久久久久久无码免费| 超级97碰碰碰碰久久久久最新| 国产综合久久久久| 久久精品国产亚洲Aⅴ香蕉| 日韩AV无码久久一区二区| 国产精品伊人久久伊人电影| 色综合久久无码五十路人妻| 久久久噜噜噜久久| 精品久久久久久中文字幕人妻最新| 久久伊人五月天论坛| 欧美大香线蕉线伊人久久| 热久久视久久精品18| 日本一区精品久久久久影院| 久久99精品久久久久婷婷| 久久亚洲精品无码aⅴ大香| 久久久久久av无码免费看大片| 国产成人精品久久免费动漫| 精品久久人人爽天天玩人人妻| 久久久国产精华液| 久久e热在这里只有国产中文精品99| 久久久噜噜噜久久中文福利| 欧美国产成人久久精品| 午夜精品久久久久| 亚洲中文字幕伊人久久无码| 久久精品中文字幕第23页| 精品欧美一区二区三区久久久| 久久美女人爽女人爽| 97久久精品人人澡人人爽| 91久久成人免费| 精品国产乱码久久久久久浪潮 | 久久99精品国产麻豆宅宅| 久久亚洲私人国产精品| 亚洲国产欧美国产综合久久| 色综合久久久久综合体桃花网|