首页 > 其他 > 详细

HDOJ 4893 Wow! Such Sequence! 线段树

时间:2014-07-30 00:23:12      阅读:374      评论:0      收藏:0      [点我收藏+]

http://acm.hdu.edu.cn/showproblem.php?pid=4893

题意:10万的区间,初始都为0,10万次操作,三种操作为单点修改,区间将每个数改成最近的斐波那契数,以及区间求和。

分析:用一个flag记录该段是否被改成斐波那契数,同时多维护一个sum1表示如果该段改成斐波那契数,区间和为多少。开始sum1为区间长度,之后在单点做了修改以后对其更新,需要的时候用其覆盖sum。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 
  6 struct T{
  7     long long sum, sum1;
  8     bool flag;
  9 }t[100100 << 2];
 10 int n, m;
 11 int c, x, y;
 12 long long f[100];
 13 void pushup(int x)
 14 {
 15     int ls = x << 1, rs = x << 1 | 1;
 16     t[x].sum = t[ls].sum + t[rs].sum;
 17     t[x].sum1 = t[ls].sum1 + t[rs].sum1;
 18 }
 19 void pushdown(int x)
 20 {
 21     if (t[x].flag){
 22         t[x<<1].sum = t[x<<1].sum1;
 23         t[x<<1].flag = true;
 24         t[x<<1|1].sum = t[x<<1|1].sum1;
 25         t[x<<1|1].flag = true;
 26         t[x].flag = false;
 27     }
 28 }
 29 void build(int x, int l, int r)
 30 {
 31     t[x].flag = false;
 32     if (l == r){
 33         t[x].flag = t[x].sum = 0;
 34         t[x].sum1 = 1;
 35         return;
 36     }
 37     int mid = l + r >> 1;
 38     build(x<<1, l, mid);
 39     build(x<<1|1, mid+1, r);
 40     pushup(x);
 41 }
 42 void add(int x, int l, int r, int p, long long val)
 43 {
 44     if (l == r){
 45         t[x].sum += val;
 46         if (t[x].sum >= f[91])
 47             t[x].sum1 = f[91];
 48         else if (t[x].sum <= 1)
 49             t[x].sum1 = 1;
 50         else{
 51             long long * p = upper_bound(f, f+92, t[x].sum);
 52             if (t[x].sum - *(p-1) <= *p - t[x].sum)
 53                 t[x].sum1 = *(p-1);
 54             else
 55                 t[x].sum1 = *p;
 56         }
 57         return;
 58     }
 59     int mid = l + r >> 1;
 60     pushdown(x);
 61     if (p <= mid)
 62         add(x<<1, l, mid, p, val);
 63     if (p > mid)
 64         add(x<<1|1, mid+1, r, p, val);
 65     pushup(x);
 66 }
 67 void tra(int x, int l, int r, int s, int e)
 68 {
 69     if (l == r){
 70         t[x].sum = t[x].sum1;
 71         return;
 72     }
 73     if (s <= l && r <= e){
 74         t[x].flag = true;
 75         t[x].sum = t[x].sum1;
 76         return;
 77     }
 78     int mid = l + r >> 1;
 79     pushdown(x);
 80     if (s <= mid)
 81         tra(x<<1, l, mid, s, e);
 82     if (mid < e)
 83         tra(x<<1|1, mid+1, r, s, e);
 84     pushup(x);
 85 }
 86 long long query(int x, int l, int r, int s, int e)
 87 {
 88     if (l == r)
 89         return t[x].sum;
 90     if (s <= l && r <= e)
 91         return t[x].sum;
 92     long long tmp = 0;
 93     int mid = l + r >> 1;
 94     pushdown(x);
 95     if (s <= mid)
 96         tmp += query(x<<1, l, mid, s, e);
 97     if (mid < e)
 98         tmp += query(x<<1|1, mid+1, r, s, e);
 99     pushup(x);
100     return tmp;
101 }
102 int main()
103 {
104     f[0] = 1; f[1] = 1;
105     for (int i = 2; i <= 91; i++)
106         f[i] = f[i-1] + f[i-2];
107     while(scanf("%d %d", &n, &m) != EOF)
108     {
109         build(1, 1, n);
110         while(m--){
111             scanf("%d %d %d", &c, &x, &y);
112             if (c == 1) add(1, 1, n, x, (long long)y);
113             if (c == 2) printf("%I64d\n", query(1, 1, n, x, y));
114             if (c == 3) tra(1, 1, n, x, y);
115         }
116     }
117     return 0;
118 }

 

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

HDOJ 4893 Wow! Such Sequence! 线段树

原文:http://www.cnblogs.com/james47/p/3876475.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!