您的位置:首页 > 产品设计 > UI/UE

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: