HDU4893--Wow! Such Sequence! (线段树 延迟标记)
2014-11-11 13:42
351 查看
Wow! Such Sequence!
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3354 Accepted Submission(s): 966
[align=left]Problem Description[/align]
Recently, Doge got a funny birthday present from his new friend, Protein Tiger from St. Beeze College. No, not cactuses. It's a mysterious blackbox.
After some research, Doge found that the box is maintaining a sequence an of n numbers internally, initially all numbers are zero, and there are THREE "operations":
1.Add d to the k-th number of the sequence.
2.Query the sum of ai where l ≤ i ≤ r.
3.Change ai to the nearest Fibonacci number, where l ≤ i ≤ r.
4.Play sound "Chee-rio!", a bit useless.
Let F0 = 1,F1 = 1,Fibonacci number Fn is defined as Fn = Fn - 1 + Fn - 2 for n ≥ 2.
Nearest Fibonacci number of number x means the smallest Fn where |Fn - x| is also smallest.
Doge doesn't believe the machine could respond each request in less than 10ms. Help Doge figure out the reason.
[align=left]Input[/align]
Input contains several test cases, please process till EOF.
For each test case, there will be one line containing two integers n, m.
Next m lines, each line indicates a query:
1 k d - "add"
2 l r - "query sum"
3 l r - "change to nearest Fibonacci"
1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, |d| < 231, all queries will be valid.
[align=left]Output[/align]
For each Type 2 ("query sum") operation, output one line containing an integer represent the answer of this query.
[align=left]Sample Input[/align]
1 1
2 1 1
5 4
1 1 7
1 3 17
3 2 4
2 1 5
[align=left]Sample Output[/align]
0
22
[align=left]Author[/align]
Fudan University
[align=left]Source[/align]
2014 Multi-University Training Contest 3
题意:
1.Add d to the k-th number of the sequence.
2.Query the sum of ai where l ≤ i ≤ r.
3.Change ai to the nearest Fibonacci number, where l ≤ i ≤ r. 就这三句话
#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 1e5 + 100; ll fab[100]; int lazy[maxn<<2]; //lazy[pos]为1 表示该区间的数为Fibonacci number。 ll sum1[maxn<<2],sum2[maxn<<2]; // sum1为原数组的和,sum2为变为Fibonacci number之后的和,维护这两个数组 void pre_solve() //预处理数前90个斐波那契数 { fab[0] = fab[1] = 1; for (int i = 2; i <= 90; i++) fab[i] = fab[i-1] + fab[i-2]; } ll find_fab(ll x) //找到距离x最近的斐波那契数 { ll ans = fab[0],delta= abs(fab[0] - x); for (int i = 0; i <= 90; i++) { if (delta > abs(x - fab[i])) { delta = abs (x - fab[i]); ans = fab[i]; } } return ans; } void push_down(int pos) { if (lazy[pos]) { lazy[pos<<1] = lazy[pos<<1|1] = lazy[pos]; lazy[pos] = 0; sum1[pos<<1] = sum2[pos<<1]; sum1[pos<<1|1] = sum2[pos<<1|1]; } } void push_up(int pos) { sum1[pos] = sum1[pos<<1] + sum1[pos<<1|1]; sum2[pos] = sum2[pos<<1] + sum2[pos<<1|1]; } void build(int l,int r,int pos) { sum1[pos] = lazy[pos] = 0; if (l == r) { sum2[pos] = 1; //初始状态 所有数都为0,距离0最近的斐波那契数是1 return; } int mid = (l + r) >> 1; build(l,mid,pos<<1); build(mid+1,r,pos<<1|1); push_up(pos); } void update_add(int l,int r,int pos,int x,int val) { if (l == r) { if (lazy[pos]) sum1[pos] = sum2[pos] + val; //如果该位置的数字为斐波那契数,那么在此基础上加val else sum1[pos] += val; //不是斐波那契数 直接加val sum2[pos] = find_fab(sum1[pos]); //sum1[pos] 改变,相应的sum2也要改变 lazy[pos] = 0; return; } push_down(pos); int mid = (l + r) >> 1; if (x <= mid) update_add(l,mid,pos<<1,x,val); else update_add(mid+1,r,pos<<1|1,x,val); push_up(pos); } void update_fab(int l,int r,int pos,int ua,int ub) { if (ua <= l && ub >= r) { sum1[pos] = sum2[pos]; lazy[pos] = 1; return; } push_down(pos); int mid = (l + r) >> 1; if (ua <= mid) update_fab(l,mid,pos<<1,ua,ub); if (ub > mid) update_fab(mid+1,r,pos<<1|1,ua,ub); push_up(pos); } ll query(int l,int r,int pos,int ua,int ub) { if (ua <= l && ub >= r ) return sum1[pos]; push_down(pos); int mid = (l + r) >> 1; ll ans = 0; if (ua <= mid) ans += query(l,mid,pos<<1,ua,ub); if (ub > mid) ans += query(mid+1,r,pos<<1|1,ua,ub); return ans; } int main(void) { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif pre_solve(); int n,m; while (~scanf ("%d%d",&n,&m)) { build(1,n,1); for (int i = 0; i < m; i++) { int op,x,y; scanf ("%d%d%d",&op,&x,&y); if (op == 1) update_add(1,n,1,x,y); if (op == 3) update_fab(1,n,1,x,y); if (op == 2) printf("%I64d\n",query(1,n,1,x,y)); } } return 0; }
相关文章推荐
- HDU4893 Wow! Such Sequence! 线段树
- Wow! Such Sequence! (线段树) hdu4893
- hdu4893 Wow! Such Sequence!,树状数组,线段树,单点修改,区间更新
- hdu4893 Wow! Such Sequence! 线段树
- HDU4893 Wow! Such Sequence!
- 【HDU】4893 Wow! Such Sequence! 线段树
- HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】
- 2014多校3 Wow! Such Sequence!线段树
- HDOJ 4893 Wow! Such Sequence! (线段树)
- HDU 4893 Wow! Such Sequence! 水线段树
- HDU 4893 Wow! Such Sequence! 解题报告(线段树)
- 线段树 + 区间更新: HDU 4893 Wow! Such Sequence!
- HDU 4893 Wow! Such Sequence!【线段树】
- HDU4893 2014多校第三场1007 Wow! Such Sequence!
- 【线段树】 HDOJ 4893 Wow! Such Sequence!
- HDU 4893 Wow! Such Sequence! (线段树)
- HDU 4893 Wow! Such Sequence! (线段树)
- HDU 4893(Wow! Such Sequence!-线段树单点修改+区间求和+改为最近Fib数)
- 【HDU 4893 多校联合】 Wow! Such Sequence!【线段树】
- HDU 4893 Wow! Such Sequence! 线段树