HDOJ 4893 Wow! Such Sequence!

题意是这样的,给定一个n个元素的数组,初始值为0,3种操作:

1 k d将第k个数增加d;

2 l r 询问区间l...r范围内数之和;

3 l r 表示将区间l...r内的数变成离他最近的斐波那契数,要求尽量小。

线段树操作题目,其中对于第三种操作用一个懒惰标记一下,表示l...r内的数是不是已经变成斐波那契数,如果是的话,求和就是其相应数的斐波那契数之和。

代码:

  1 //Template updates date: 20140718
  2 #include <bits/stdc++.h>
  3 #define  esp 1e-6
  4 #define  inf 0x3f3f3f3f
  5 #define  pi acos(-1.0)
  6 #define  pb push_back
  7 #define  lson l, m, rt<<1
  8 #define  rson m+1, r, rt<<1|1
  9 #define  lowbit(x) (x&(-x))
 10 #define  mp(a, b) make_pair((a), (b))
 11 #define  bit(k) (1<<(k))
 12 #define  iin  freopen("pow.in", "r", stdin);
 13 #define  oout freopen("pow.out", "w", stdout);
 14 #define  in  freopen("solve_in.txt", "r", stdin);
 15 #define  out freopen("solve_out.txt", "w", stdout);
 16 #define  bug puts("********))))))");
 17 #define  Inout iin oout
 18 #define  inout in out
 19
 20 #define  SET(a, v) memset(a, (v), sizeof(a))
 21 #define  SORT(a)   sort((a).begin(), (a).end())
 22 #define  REV(a)    reverse((a).begin(), (a).end())
 23 #define  READ(a, n) {REP(i, n) cin>>(a)[i];}
 24 #define  REP(i, n) for(int i = 0; i < (n); i++)
 25 #define  VREP(i, n, base) for(int i = (n); i >= (base); i--)
 26 #define  Rep(i, base, n) for(int i = (base); i < (n); i++)
 27 #define  REPS(s, i) for(int i = 0; (s)[i]; i++)
 28 #define  pf(x) ((x)*(x))
 29 #define  mod(n) ((n))
 30 #define  Log(a, b) (log((double)b)/log((double)a))
 31 #define Srand() srand((int)time(0))
 32 #define random(number) (rand()%number)
 33 #define random_range(a, b) (int)(((double)rand()/RAND_MAX)*(b-a) + a)
 34
 35 using namespace std;
 36 typedef long long  LL;
 37 typedef unsigned long long ULL;
 38 typedef vector<int> VI;
 39 typedef pair<int,int> PII;
 40 typedef vector<PII> VII;
 41 typedef vector<PII, int> VIII;
 42 typedef VI:: iterator IT;
 43 typedef map<string, int> Mps;
 44 typedef map<int, int> Mpi;
 45 typedef map<int, PII> Mpii;
 46 typedef map<PII, int> Mpiii;
 47 const int maxm = 140000 + 1000;
 48
 49 LL f[92];
 50 int n, m;
 51 LL sum[maxm<<2], sum1[maxm<<2], cover[maxm<<2];
 52
 53 void pre() {
 54     f[0] = f[1] = 1;
 55     Rep(i, 2, 92) {
 56         f[i] = f[i-1] + f[i-2];
 57     }
 58 }
 59 void PushDown(int rt) {
 60     if(cover[rt]) {
 61         cover[rt] = 0;
 62         cover[rt<<1] = cover[rt<<1|1] = 1;
 63         sum[rt<<1] = sum1[rt<<1];
 64         sum[rt<<1|1] = sum1[rt<<1|1];
 65     }
 66 }
 67 void PushUp(int rt) {
 68     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
 69     sum1[rt] = sum1[rt<<1]+sum1[rt<<1|1];
 70 }
 71 void build(int l, int r, int rt) {
 72     if(l == r) {
 73         sum[rt] = 0;
 74         sum1[rt] = 1;
 75         cover[rt] = 0;
 76         return ;
 77     }
 78     int m = (l+r)>>1;
 79     build(lson);
 80     build(rson);
 81     PushUp(rt);
 82     cover[rt] = 0;
 83 }
 84
 85 void update(int l, int r, int rt, int k, int d) {
 86     if(l == k && r == k) {
 87         sum[rt] += d;
 88         int b = upper_bound(f+1, f+92, sum[rt]) - f;
 89         if(abs(f[b]-sum[rt]) >= abs(f[b-1]-sum[rt]))
 90             sum1[rt] = f[b-1];
 91         else
 92             sum1[rt] = f[b];
 93         return;
 94     }
 95     PushDown(rt);
 96     int m = (l+r)>>1;
 97     if(k <= m)
 98         update(lson, k, d);
 99     else update(rson, k, d);
100     PushUp(rt);
101 }
102 void update1(int L, int R, int l, int r, int rt) {
103     if(L <=l && R >= r) {
104         cover[rt] = 1;
105         sum[rt] = sum1[rt];
106         return;
107     }
108     PushDown(rt);
109     int m = (l+r)>>1;
110     if(L <= m)
111         update1(L, R, lson);
112     if(R > m)
113         update1(L, R, rson);
114     PushUp(rt);
115 }
116 LL query(int L, int R, int l, int r, int rt) {
117     if(L <= l && R >= r) {
118         return sum[rt];
119     }
120     int m = (l+r)>>1;
121     PushDown(rt);
122     LL ans = 0;
123     if(L <= m)
124         ans += query(L, R, lson);
125     if( R > m)
126         ans += query(L, R, rson);
127     return ans;
128 }
129 int main() {
130
131     pre();
132     while(scanf("%d%d", &n, &m) == 2) {
133         build(1, n, 1);
134         REP(i, m) {
135             int u, l, r;
136             scanf("%d%d%d", &u, &l, &r);
137             if(u == 2) {
138                 printf("%I64d\n", query(l, r, 1, n, 1));
139             } else if(u == 1) {
140                 update(1, n, 1, l, r);
141             } else {
142                 update1(l, r, 1, n, 1);
143             }
144         }
145     }
146     return 0;
147 }

HDOJ 4893 Wow! Such Sequence!,布布扣,bubuko.com

时间: 2024-10-14 11:30:10

HDOJ 4893 Wow! Such Sequence!的相关文章

HDOJ 4893 Wow! Such Sequence! 线段树

http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:10万的区间,初始都为0,10万次操作,三种操作为单点修改,区间将每个数改成最近的斐波那契数,以及区间求和. 分析:用一个flag记录该段是否被改成斐波那契数,同时多维护一个sum1表示如果该段改成斐波那契数,区间和为多少.开始sum1为区间长度,之后在单点做了修改以后对其更新,需要的时候用其覆盖sum. 1 #include<cstdio> 2 #include<cstring>

hdu 4893 Wow! Such Sequence!(线段树)

题目链接:hdu 4983 Wow! Such Sequence! 题目大意:就是三种操作 1 k d, 修改k的为值增加d 2 l r, 查询l到r的区间和 3 l r, 间l到r区间上的所以数变成最近的斐波那契数,相等的话取向下取. 解题思路:线段树,对于每个节点新增一个bool表示该节点以下的位置是否都是斐波那契数. #include <cstdio> #include <cstring> #include <cstdlib> #include <algor

HDU 4893 Wow! Such Sequence! 水线段树

思路: 线段树走起.. 写完这题就退役T^T 单点更新的时候直接找到这个点的最近fib,然后维护当前和 和 fib的和 #include<stdio.h> #include<string.h> #include<iostream> #include<math.h> #include<algorithm> #include<queue> #include<map> #include<set> #include&l

hdu 4893 Wow! Such Sequence!(线段树功能:单点更新,区间更新相邻较小斐波那契数)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 --------------------------------------------------------------------------------------------------------------------------------------------

HDU 4893 Wow! Such Sequence! (线段树)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 838    Accepted Submission(s): 245 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

hdu 4893 Wow! Such Sequence!

http://acm.hdu.edu.cn/showproblem.php?pid=4893 三种操作: 1 k d - "add" 2 l r - "query sum" 3 l r - "change to nearest Fibonacci" 节点附件三个值: s1:由lazy控制的区间的正确的和. s2:区间内与所有数相近的fib数之和,随着单点更新而更新. col:lazy,标记区间是否全部取fib数,是取1,否则取0. 询问区间的和时

线段树 + 区间更新: HDU 4893 Wow! Such Sequence!

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2234    Accepted Submission(s): 657 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

HDU 4893 Wow! Such Sequence 线段树暴力

题意:n个数 初始为0,三个操作:给某个数加上d,查询区间和,把区间[l,r]中每个a[i]变为离a[i]最近的斐波那契数,n,m<=1e5. 无操作1情况下,每个点最多变化一次,每次修改logn,算上操作1 最坏情况下修改n+m次 O((n+m)logn). 对区间设个标记 线段树暴力即可. #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; const int

HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)

磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add  把d加到第k个数上去2 l r - query sum 计算l到r所有数的和3 l r - change to nearest Fibonacci 把l到r的数修改为距离它最近的斐波那契数 节点附件三个值: s1:由lazy控制的区间的正确的和. s2:区间内与所有数相近的fib数之和,随着单点更新而更新. col:laz