#31041: 排名順序


luray0601@gmail.com (QWERTYPIG)

學校 : 臺北市私立復興實驗高級中學
編號 : 139334
來源 : [140.112.238.240]
最後登入時間 :
2024-11-19 19:45:37
d788. 排名順序 | From: [1.169.87.57] | 發表日期 : 2022-07-06 22:21

主要想法是利用BIT或線段樹來執行單點加值及區間求和(標籤有AVL tree但我不知道那是甚麼QQ)

每次新增分數前先單點修改讓A這個點的值加上1,之後在看分數在他之前的有多少人,人數加1就是排名(假設新增分數為A,那就是A+1~100000的區間和+1)

BIT和線段樹加值和求和的複雜度都是O(logn),時間上是沒問題的

struct BIT{
    int sz;
    vector<int>dat;
    void init(){
        sz=100000;
        dat.assign(sz+1,0);
        return;
    }
    void upd(int id,int x){
        for(int i=id;i<=sz;i+=i&-i)dat[i]+=x;
        return;
    }
    int sum(int id){
        int ans=0;
        for(int i=id;i>0;i-=i&-i)ans+=dat[i];
        return ans;
    }
}bit;

這邊附上BIT的程式碼(線段樹程式碼比較長懶得打)

其中init是初始化,upd是單點更新,sum是求前綴和

假設新增分數是A,

就upd(A,1),再輸出sum(1000000)-sum(A)+1

 
ZeroJudge Forum