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

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

            国内精品久久久人妻中文字幕| 日本亚洲色大成网站WWW久久| 国内精品伊人久久久久影院对白| 久久久久亚洲精品日久生情| 久久综合欧美成人| 国产成人综合久久精品尤物| 99久久精品国产一区二区三区| 久久婷婷五月综合97色| 久久久久国产一区二区三区| 久久中文字幕一区二区| 老司机国内精品久久久久| 久久久久久久久久久久中文字幕| 色妞色综合久久夜夜| 亚洲色欲久久久久综合网| 人妻无码久久精品| 久久精品桃花综合| 久久久久久精品成人免费图片| 久久无码AV中文出轨人妻| 亚洲午夜福利精品久久| 精品国产乱码久久久久久呢| 久久精品亚洲AV久久久无码| 亚洲中文字幕无码久久综合网| 久久这里只有精品18| 久久这里有精品视频| 久久精品无码av| 国产精品久久久天天影视| 九九热久久免费视频| 一本一道久久精品综合| 久久成人18免费网站| 色99久久久久高潮综合影院| 伊色综合久久之综合久久| 亚洲中文久久精品无码ww16| 久久精品国产影库免费看| 精品久久久久一区二区三区| 久久亚洲日韩看片无码| 国产午夜久久影院| 久久国产视频网| 久久精品国产亚洲AV大全| 久久99精品久久久久久9蜜桃| 久久久国产99久久国产一| 久久国产亚洲精品麻豆|