[題目]
xlk覺得《上帝造題的七分鐘》不太過癮,於是有了第二部。
"第一分鐘,x說,要有數列,於是便給定了乙個正整數數列。
第二分鐘,l說,要能修改,於是便有了對一段數中每個數都開平方(下取整)的操作。
第三分鐘,k說,要能查詢,於是便有了求一段數的和的操作。
第四分鐘,彩虹喵說,要是noip難度,於是便有了資料範圍。
第五分鐘,詩人說,要有韻律,於是便有了時間限制和記憶體限制。
第六分鐘,和雪說,要省點事,於是便有了保證運算過程中及最終結果均不超過64位有符號整數型別的表示範圍的限制。
第七分鐘,這道題終於造完了,然而,造題的神牛們再也不想寫這道題的程式了。"
——《上帝造題的七分鐘·第二部》
所以這個神聖的任務就交給你了
對於100%的資料,1<=n<=100000,1<=l<=r<=n,數列中的數大於0,且不超過1e12。
[演算法]
線段樹[分析]
題目很容易讓人想到線段樹,但是區間sqrt這個操作……實在是蛋疼。不能打懶標記,乙個乙個改的話一次就是nlog2n的效率。然而要注意1e12開根最多也就開六七次,這樣機會就來了。給線段樹中的每個元素乙個標記flag,當這一段中所有的元素都被開成1時,給它打上標記,以後修改的時候遇到flag == true的就直接return 。這樣整體的修改複雜度就降到 nlog2n了
[注意]
題目中提到了l和r不一定誰大誰小,結果做的時候還是忘了……最悲催的是剛開始竟然忘了寫flag優化,導致不停tle,還以為是常數上的問題,以後要注意了……
[**]
#include #include #include #include #include using namespace std;
#define maxn 101000
#define maxnode 400000
long long a[maxn];
long long sum[maxnode] = ;
bool flag[maxnode] = ;
int ll[maxnode], rr[maxnode];
int n, m;
void build(int now, int left, int right)
int mid = (left + right) >> 1;
build(now << 1, left, mid);
build((now << 1) + 1, mid + 1, right);
sum[now] = sum[now << 1] + sum[(now << 1) + 1];
flag[now] = flag[now << 1] & flag[(now << 1) + 1];
}void change(int now, int l, int r)
int mid = (left + right) >> 1;
if (l <= mid) change(now << 1, l, r);
if (r > mid) change((now << 1) + 1, l, r);
sum[now] = sum[now << 1] + sum[(now << 1) + 1];
flag[now] = flag[now << 1] & flag[(now << 1) + 1];
}long long query(int now, int l, int r)
int main()
if (k == 0)
change(1, l, r);
else
printf("%lld\n", query(1, l, r));
}}
bzoj3038 上帝造題的七分鐘2 線段樹
ac通道 線段樹是我最不熟悉的東西之一,於是找幾道題搞搞 這題就很簡單了 有乙個神奇的優化 如果乙個結點值為0或者1就不再更新 如果一棵樹左右兒子都不再更新,它也不再更新 include include include include include include includeusing nam...
bzoj 3038 上帝造題的七分鐘2
time limit 3 sec memory limit 128 mb submit 923 solved 413 submit status discuss xlk覺得 上帝造題的七分鐘 不太過癮,於是有了第二部。第一分鐘,x說,要有數列,於是便給定了乙個正整數數列。第二分鐘,l說,要能修改,於...
BZOJ 3038 上帝造題的七分鐘2
description xlk覺得 上帝造題的七分鐘 不太過癮,於是有了第二部。第一分鐘,x說,要有數列,於是便給定了乙個正整數數列。第二分鐘,l說,要能修改,於是便有了對一段數中每個數都開平方 下取整 的操作。第三分鐘,k說,要能查詢,於是便有了求一段數的和的操作。第四分鐘,彩虹喵說,要是noip...