跳蚤(線段樹)

2022-05-21 15:03:09 字數 1815 閱讀 4859

nirobc 姐姐奴役了一群跳蚤,並隨時把它們丟到一台圖靈機的紙帶上。

一開始,紙帶上沒有跳蚤,每乙個時刻,nirobc 姐姐可能做以下三個操作之一:

在位置x 放置乙隻每次向右(座標增大方向)跳t 格的跳蚤。

命令所有跳蚤向右跳躍一次,跳躍的距離為各自的t。

給定區間[l,r],求該區間內跳蚤的個數。

第一行乙個正整數q,表示操作個數。

接下來q 行,這q 行中的第i 行含有若干個整數,描述第i 個操作。

(1) 若第乙個整數為1,則緊跟兩個整數xi 和ti,表示在xi 的位置放置乙隻每次向右跳躍ti 格的跳蚤。

(2) 若第乙個整數為2,則命令所有跳蚤向右跳躍一次。

(3) 若第乙個整數為3,則緊跟兩個整數li 和ri,你需要輸出此時區間[li, ri]中跳蚤的數量。

對於每乙個3 號操作,輸出一行乙個整數,表示該詢問的答案。

101 4 1

1 2 2

3 3 5

2 33 5

2 33 5

3 6 6

1 5 1

3 3 512

021取\(b=200\),對於\(t\leq b\)的跳蚤,直接建\(b\)顆線段樹,將\(t\)相同的跳蚤放在一起。

對於\(t>b\)的跳蚤,最多跳\(1e5/200\)次就不會在被記錄到,我們暴力模擬,並用樹狀陣列記錄下它們的位置。

另外,設\(c\)為到\(i\)為止的跳躍次數,對於所有\(t\)相同的跳蚤來說,每次跳躍並不改變其相對位置,且其相對位置只與插入時間有關。

所以我們每次只需把跳蚤插入到\(x-c*t\)的位置即可。

\\#pragma gcc optimize(2)

\\#pragma gcc optimize(3, "ofast", "inline")

#include using namespace std;

typedef long long ll;

typedef unsigned long long ull;

typedef pairpii;

const int n=1e6+5;

const ll mod=100000007;

const double eps=1e-5;

const double pi=acos(-1);

#define ls p<<1

#define rs p<<1|1

int c[n],tl,rt[n],n;

int c;

struct node

a[n];

pii q[n];

void add(int x,int d)

int ask(int x)

void build(int &p,int l,int r,int x)

int mid=l+r>>1;

if(x<=mid) build(a[p].l,l,mid,x);

else build(a[p].r,mid+1,r,x);

a[p].dat=a[a[p].l].dat+a[a[p].r].dat;

}int query(int p,int l,int r,int x,int y)

int main()

; }

else build(rt[t],-t*100000,100000,x-c*t);

}if(op==2);}

tl=cnt;

for(int i=1;i<=cnt;i++) add(q[i].first,1);

}if(op==3)

}return 0;

}

線段樹 跳蚤

nirobc 姐姐奴役了一群跳蚤,並隨時把它們丟到一台圖靈機的紙帶上。一開始,紙帶上沒有跳蚤,每乙個時刻,nirobc 姐姐可能做以下三個操作之一 在位置x 放置乙隻每次向右 座標增大方向 跳t 格的跳蚤。命令所有跳蚤向右跳躍一次,跳躍的距離為各自的t。給定區間 l,r 求該區間內跳蚤的個數。第一行...

線段樹 02 構建線段樹

public inte ce merger 不能再縮小的基本問題是 對treeindex指向的節點的情況進行討論 public class segmenttree 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treei...

線段樹 01 線段樹基礎

物理上 public class segmenttree public int getsize public e get int index 返回完全二叉樹的陣列表示中,乙個索引所表示的元素的左孩子節點的索引 private int leftchild int index 返回完全二叉樹的陣列表示中...