題目背景
xlk覺得《上帝造題的七分鐘》不太過癮,於是有了第二部。
題目描述
"第一分鐘,x說,要有數列,於是便給定了乙個正整數數列。
第二分鐘,l說,要能修改,於是便有了對一段數中每個數都開平方(下取整)的操作。
第三分鐘,k說,要能查詢,於是便有了求一段數的和的操作。
第四分鐘,彩虹喵說,要是noip難度,於是便有了資料範圍。
第五分鐘,詩人說,要有韻律,於是便有了時間限制和記憶體限制。
第六分鐘,和雪說,要省點事,於是便有了保證運算過程中及最終結果均不超過64位有符號整數型別的表示範圍的限制。
第七分鐘,這道題終於造完了,然而,造題的神牛們再也不想寫這道題的程式了。"
——《上帝造題的七分鐘·第二部》
所以這個神聖的任務就交給你了。
輸入輸出格式
輸入格式:
第一行乙個整數 n ,代表數列中數的個數。
第二行 n 個正整數,表示初始狀態下數列中的數。
第三行乙個整數 m ,表示有 m 次操作。
接下來 mm 行每行三個整數k,l,r,
k=0表示給 [l,r] 中的每個數開平方(下取整)
k=1表示詢問 [l,r] 中各個數的和。
資料中有可能 l>r ,所以遇到這種情況請交換l和r。
輸出格式:
對於詢問操作,每行輸出乙個回答。
錯誤日誌: 沒有弄清選擇巢狀的集合關係, 以後遞迴函式判斷返回盡量在函式開頭而不是函式入口處
要求維護區間和和區間開方
乍一眼看很難下手, 但是通過觀察, 得出以下結論:
乙個 \(64\)位 整數最多隻會被開方 \(6\) 次, 然後就變成 \(1\)
\(\sqrt = 1\)
\(\sqrt = 0\)
所以發現, 乙個數最多會被修改 \(6\) 次, 考慮線段樹暴力修改
於是有了下列含有剪枝思想的修改函式
void update(ll id, ll l, ll r)
ll mid = (tree[id].l + tree[id].r) >> 1;
if(mid < l)update(rid, l, r);
else if(mid >= r)update(lid, l, r);
else update(lid, l, mid), update(1, mid + 1, r);
pushup(id);
}
#include#include#include#include#include#include#include#define ll long long
using namespace std;
ll rd()
while(c >= '0' && c <= '9')
return flag * out;
}const ll maxn = 200019;
ll num, na;
ll v[maxn];
#define lid (id << 1)
#define rid (id << 1) | 1
struct seg_treetree[maxn << 2];
void pushup(ll id)
void build(ll id, ll l, ll r)
ll mid = (l + r) >> 1;
build(lid, l, mid), build(rid, mid + 1, r);
pushup(id);
}void update(ll id, ll l, ll r)
ll mid = (tree[id].l + tree[id].r) >> 1;
if(mid < l)update(rid, l, r);
else if(mid >= r)update(lid, l, r);
else update(lid, l, mid), update(1, mid + 1, r);
pushup(id);
}ll get_sum(ll id, ll l, ll r)
ll mid = (tree[id].l + tree[id].r) >> 1;
if(mid < l)return get_sum(rid, l, r);
else if(mid >= r)return get_sum(lid, l, r);
else return get_sum(lid, l, mid) + get_sum(rid, mid + 1, r);
}int main()
return 0;
}
P4145 上帝造題的七分鐘2 花神遊歷各國
xlk覺得 上帝造題的七分鐘 不太過癮,於是有了第二部。第一分鐘,x說,要有數列,於是便給定了乙個正整數數列。第二分鐘,l說,要能修改,於是便有了對一段數中每個數都開平方 下取整 的操作。第三分鐘,k說,要能查詢,於是便有了求一段數的和的操作。第四分鐘,彩虹喵說,要是noip難度,於是便有了資料範圍...
P4145 上帝造題的七分鐘 2 花神遊歷各國
include include include include include include include include include include using namespace std typedef long long ll const int n 1e6 5 ll a n stru...
洛谷P4145上帝造題的七分鐘 區間修改
題目 區間開平方,可以發現其實開幾次就變成1,不需要開了,所以標記一下,每次只去開需要開的地方 原來寫的並查集跳過1或0,然而wa.其實是沒有記錄原陣列的值,因為樹狀陣列存的是修改量 如果a陣列 原陣列 開int會re!改成線段樹,本來想著是這一段區間和只要小於等於其長度就可以跳過了,然而仔細想想完...