線段樹 關於整段修改成a i ,並查詢

2022-06-19 03:45:07 字數 1692 閱讀 5710

肯定要提前預留出di 陣列,然後就是線段樹。

剛開始以為 因子數=i-phi[i]+1

後來發現並不是,4和6不是因子關係,但是他們不是互質的,這兩個的含義不一樣, 並不是互補的

我們發現資料範圍為1e6,然後一步步迭代 最終都會變成 1或者 2  d[1]=1  d[2]=2;  最多可迭代6次。

剛開始按照線段樹一般解法,用update 區間修改,是這點的話,就變成d[i],不是的話,就往下放,並且要push-up

查詢用long long 

後來發現超時了,我們發現不是每次都需要往下放的,就比如 d[2]=d[d[2]],就沒有任何意義。

我們用乙個最大值來定義區間的最大值,如果最大值<=2,那麼就不必往下放,節約時間。

1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 

7 #include 8 #include 9 #include 10 #include 11

using

namespace

std;

12 typedef long

long

ll;13

const

int inf=0x7fffffff;14

const

int n=1e6+100;15

const

int m=3*1e5+100

;16 ll tree[m<<2],d[n],mx[m<<2

];17

intn,m;

18void

init()

1926

void push_up(int

rt)27

31void build(int rt,int l,int

r)32

39int m=(l+r)/2

;40 build(rt<<1

,l,m);

41 build(rt<<1|1,m+1

,r);

42push_up(rt);43}

44void update(int l,int r,int rt,int l,int

r)45

52int m=(l+r)/2;53

if(l<=m) update(l,r,rt<<1

,l,m);

54if(r>m) update(l,r,rt<<1|1,m+1

,r);

55push_up(rt);56}

57 ll query(int l,int r,int rt,int l,int

r)58

66int

main()

6780

81return0;

82 }

view code

解決這種題目的方法:

1.提前寫出d[i]陣列

2.線段樹

3.看是否可以優化。

線段樹區間修改和查詢和單點查詢(線段樹模板1)

如題,已知乙個數列,你需要進行下面兩種操作 將某區間每乙個數加上 kk。求出某區間每乙個數的和。第一行包含兩個整數 n,mn,m,分別表示該數列數字的個數和操作的總個數。第二行包含 nn 個用空格分隔的整數,其中第 ii 個數字表示數列第 ii 項的初始值。接下來 mm 行每行包含 33 或 44 ...

線段樹單點修改區間查詢

這是一道模板題。給定數列 a 1 a 2 a n 你需要依次進行 qq 個操作,操作有兩類 1 i x 給定 i,x,將 a i 加上 x 2 l r 給定 l,r,求 ri la i 的值 換言之,求 a l a l 1 a r 的值 input 第一行包含 2 個正整數 n,q,表示數列長度和詢...

線段樹(點查詢 區間查詢 區間修改)模板

簡單記錄一下自己的 以後方便複習 其實有了這樣子的乙個模板,題目變式自己改改就可以,比如說加減變成乘除等等。pragma gcc optimize 3,ofast inline include include include include include include include inclu...