肯定要提前預留出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 #includeview code7 #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 }
解決這種題目的方法:
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...