hdu 4893 Wow! Such Sequence!(线段树和树状数组实现)--2014 Multi-University Training Contest 3
来源:互联网 发布:淘宝哪家牛仔裤质量好 编辑:程序博客网 时间:2024/06/05 04:57
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893
Wow! Such Sequence!
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 435 Accepted Submission(s): 133
Problem Description
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.
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.
Input
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.
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.
Output
For each Type 2 ("query sum") operation, output one line containing an integer represent the answer of this query.
Sample Input
1 12 1 15 41 1 71 3 173 2 42 1 5
Sample Output
022
Source
2014 Multi-University Training Contest 3
Recommend
hujie | We have carefully selected several similar problems for you: 4896 4895 4894 4892 4890
一道线段树的问题,当然也可以用树状数组实现,难点主要在把一个区间的数改成离自己最近的斐波那契数的那一块。需要进行优化,我的做法是通过set记录,已经处理过的节点,避免一个节点被重复处理,因为重复处理的结果肯定是一样的。
线段树实现:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <string>#include <bitset>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <cstdlib>using namespace std;#define CLR(A) memset(A,0,sizeof(A))typedef long long ll;const int MAX=400010;struct Node{ int l,r; ll v;}tree[MAX];ll f[100];int del[MAX];void build(int id,int l,int r){ tree[id].l=l;tree[id].r=r;tree[id].v=0; if(l==r) return; int m=(l+r)>>1; build(id<<1,l,m); build(id<<1|1,m+1,r);}void add(int id,int i,ll v){ if(tree[id].l==tree[id].r){ tree[id].v+=v; return; } int m=(tree[id].l+tree[id].r)>>1; if(i<=m) add(id<<1,i,v); else add(id<<1|1,i,v); tree[id].v=tree[id<<1].v+tree[id<<1|1].v;}ll query(int id,int l,int r){ if(l==tree[id].l&&r==tree[id].r) return tree[id].v; int m=(tree[id].l+tree[id].r)>>1; if(r<=m) return query(id<<1,l,r); if(l>m) return query(id<<1|1,l,r); return query(id<<1,l,m)+query(id<<1|1,m+1,r);}void init(){ CLR(f); f[0]=1;f[1]=1; for(int i=2;i<=91;i++) f[i]=f[i-1]+f[i-2];}int main(){ int n,m; init(); while(~scanf("%d%d",&n,&m)){ build(1,1,n); set<int>st; set<int>::iterator it; for(int i=1;i<=n;i++) st.insert(i); while(m--){ int ord,a,b; scanf("%d%d%d",&ord,&a,&b); switch(ord){ case 1: add(1,a,b); st.insert(a); break; case 2: printf("%I64d\n",query(1,a,b)); break; case 3: it=lower_bound(st.begin(),st.end(),a); del[0]=0; for(;it!=st.end()&&((*it)<=b);it++){ int p=*it; del[++del[0]]=p; ll u=query(1,p,p),k; int t=lower_bound(f+1,f+92,u)-f; if(abs(f[t]-u)<abs(f[t-1]-u)) k=f[t]; else k=f[t-1]; add(1,p,-u);add(1,p,k); } for(int i=1;i<=del[0];i++) st.erase(del[i]); break; default:; } } } return 0;}
树状态数组实现:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <string>#include <bitset>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <cstdlib>using namespace std;#define CLR(A) memset(A,0,sizeof(A))typedef long long ll;const int MAX=100010;ll bit[MAX];ll f[100];int del[MAX];int n,m;inline int lowbit(int t){return t&-t;}ll sum(int i){ ll s=0; while(i>0){ s+=bit[i]; i-=lowbit(i); } return s;}void add(int i,ll v){ while(i<=n){ bit[i]+=v; i+=lowbit(i); }}void init(){ CLR(f); f[0]=1;f[1]=1; for(int i=2;i<=91;i++) f[i]=f[i-1]+f[i-2];}int main(){ init(); while(~scanf("%d%d",&n,&m)){ CLR(bit); set<int>st; set<int>::iterator it; for(int i=1;i<=n;i++) st.insert(i); while(m--){ int ord,a,b; scanf("%d%d%d",&ord,&a,&b); switch(ord){ case 1: add(a,b); st.insert(a); break; case 2: printf("%I64d\n",sum(b)-sum(a-1)); break; case 3: it=lower_bound(st.begin(),st.end(),a); del[0]=0; for(;it!=st.end()&&((*it)<=b);it++){ int p=*it; del[++del[0]]=p; ll u=sum(p)-sum(p-1),k; int t=lower_bound(f+1,f+92,u)-f; if(abs(f[t]-u)<abs(f[t-1]-u)) k=f[t]; else k=f[t-1]; add(p,-u);add(p,k); } for(int i=1;i<=del[0];i++) st.erase(del[i]); break; default:; } } } return 0;}
0 0
- hdu 4893 Wow! Such Sequence!(线段树和树状数组实现)--2014 Multi-University Training Contest 3
- 2014 Multi-University Training Contest 3 1007 && HDU 4893 Wow! Such Sequence ! (线段树)
- 【2014 Multi-University Training Contest 3 1007】/【HDU 4893】 Wow! Such Sequence!
- hdu 4893 Wow! Such Sequence! 2014 Multi-University Training Contest 3
- hdu 4915 Parenthese sequence--2014 Multi-University Training Contest 5
- hdu 4893 Wow! Such Sequence! 线段树
- hdu 4893 Wow! Such Sequence!(线段树)
- HDU Wow! 4893 Such Sequence!(线段树)
- 【HDU】4893 Wow! Such Sequence! 线段树
- HDU 4893 Wow! Such Sequence!(线段树)
- HDU 4893 Wow! Such Sequence! 线段树
- hdu 5289 - Assignment(2015 Multi-University Training Contest 1 )单调队列+RMQ+树状数组
- hdu 5775 Bubble Sort(2016 Multi-University Training Contest 4——树状数组)
- hdu 5792 World is Exploding(2016 Multi-University Training Contest 5——树状数组)
- 2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树区间更新+差分数组)
- HDU 4893 Wow! Such Sequence! (线段树)
- HDU 4893 Wow! Such Sequence! 解题报告(线段树)
- HDU 6078 Wavel Sequence (dp + 树状数组, 2017 Multi-Univ Training Contest 4)
- UVa 401 Palindromes(字符串,回文)
- HDUJ 1069 Monkey and Banana
- hdu-2053-Switch Game
- HDU 1253 胜利大逃亡(BFS)
- http://poj.org/problem?id=2413
- hdu 4893 Wow! Such Sequence!(线段树和树状数组实现)--2014 Multi-University Training Contest 3
- Hibernat4.3.5+JPA
- 使用数据挖掘软件Rapidminer进行关联规则分析
- JSP简单练习-EL表达式操作JavaBean
- Java引用类型详解
- hdu1008 Elevator
- HDU4891 The Great Pan
- java使用jacob调用OCX控件1
- Oracle XE DB 32bit upgrade to 64 bit on platform win7