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

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

            伊人伊成久久人综合网777| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久久WWW成人免费精品| 99久久香蕉国产线看观香| 91精品国产色综合久久| 伊人热热久久原色播放www| 亚洲精品无码专区久久久| 青青热久久国产久精品 | 久久香综合精品久久伊人| 国产日韩久久免费影院| 热久久最新网站获取| 久久国产视频网| 久久久久se色偷偷亚洲精品av| 久久亚洲电影| 久久久久久极精品久久久| 久久精品国产亚洲αv忘忧草| 91精品国产91久久| 一级做a爱片久久毛片| 久久香综合精品久久伊人| 久久久久久国产精品无码下载| 久久99国产综合精品女同| 99久久婷婷免费国产综合精品| 日韩欧美亚洲综合久久影院Ds| 国产精品久久久久国产A级| 亚洲国产小视频精品久久久三级 | 国内精品久久久久久久久| 久久久99精品一区二区| 日本精品久久久久中文字幕| 99久久精品久久久久久清纯| 精品无码久久久久久午夜| 影音先锋女人AV鲁色资源网久久| 日本强好片久久久久久AAA| 久久精品极品盛宴观看| 免费精品国产日韩热久久| 久久亚洲欧洲国产综合| 亚洲国产综合久久天堂| 久久精品国产福利国产琪琪| 成人精品一区二区久久久| 久久久久亚洲?V成人无码| 亚洲精品tv久久久久| 亚洲美日韩Av中文字幕无码久久久妻妇|