1. 程式人生 > >Serega and Fun CodeForces - 455D (分塊 或 splay)

Serega and Fun CodeForces - 455D (分塊 或 splay)

rep highlight brush 鏈表 and lar 大致 位置 ()

大意:給定n元素序列, 2種操作

  • 將區間$[l,r]$循環右移1位
  • 詢問$[l,r]$中有多少個等於k的元素

現在給定q個操作, 輸出操作2的詢問結果, 強制在線

思路1: 分塊

每個塊內維護一個鏈表, 循環右移相當於刪除一個元素, 再插入一個元素, 每個塊內再維護一個桶統計元素個數即可

分塊好久沒寫過了, 先放個分塊大致流程

void init() {
    //sqn是分塊數, blo[i]是位置i所屬塊的編號
    //L[i], R[i]是位置i所屬塊的左右邊界                               
    sqn = sqrt(n);
    REP(i,1,n) {
        blo[i] = (i-1)/sqn+1;
        L[i] = (blo[i]-1)*sqn+1;
        R[i] = blo[i]*sqn;
    }
}

void work(int l, int r) {
    REP(i,l,R[l]) {
        //前半段暴力
    }
    REP(i,blo[l]+1,blo[r]+1) {
        //處理中間每個塊
    }
    if (blo[l]!=blo[r]) {
        REP(i,L[r],r) {
            //後半段暴力
        }
    }
}

Serega and Fun CodeForces - 455D (分塊 或 splay)