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

 大意:给定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) {
            //后半段暴力
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/uid001/p/10423456.html
今日推荐