码迷,mamicode.com
首页 > 其他好文 > 详细

hihoCoder #1078 : 线段树的区间修改

时间:2015-05-15 22:45:31      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:

 

思路:

 

技术分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=100010;
 4 int n, q, op, l, r, flag, sma;
 5 int w[N];
 6 int ans[N];
 7 
 8 void cal(int t)//从t开始计算,ans[i]表示1~i的和
 9 {
10     for(int i=t; i<=n; i++)
11         ans[i]=ans[i-1]+w[i];
12 }
13 
14 int main()
15 {
16     //freopen("input.txt", "r", stdin);
17     sma=0x7fffffff;
18     cin>>n;
19     for(int i=0; i<n; i++)    scanf("%d",&w[i+1]);
20     cin>>q;
21     cal(1);//先算一次
22     for(int i=0; i<q; i++)
23     {
24         scanf("%d",&op);
25         int a,b,c;
26         if(op)  //修改
27         {
28             scanf("%d%d%d",&a,&b,&c);
29             for(int i=a; i<=b; i++)    w[i]=c;
30             if(a<sma)
31                 sma=a;//需要修改的地方sma~n。若多次修改,只需要一次从最小的sma开始修改
32             flag=a;//需要修改的标志
33         }
34         else    //查询
35         {
36             if(flag)
37             {
38                 cal(sma);
39                 sma=0x7fffffff;
40                 flag=0;
41             }
42             scanf("%d%d", &a,&b);
43             printf("%d\n",ans[b]-ans[a-1]);
44         }
45     }
46     return 0;
47 }
偷懒的TLE代码

 

技术分享
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int N=100010;
  4 int n, q, L, R, op, a, b, W;
  5 bool flag[N];
  6 struct node
  7 {
  8     int v;
  9     bool flag;
 10     node *ll,*rr;
 11 
 12 };
 13 
 14 node* create()  //创建节点
 15 {
 16     node *tmp=new(node);
 17     tmp->flag=tmp->v=0;
 18     tmp->ll=tmp->rr=0;
 19     return tmp;
 20 }
 21 
 22 node* init_tree(int l,int r)    //初始化树
 23 {
 24     node *tmp=create();
 25     if(l==r)
 26     {
 27         scanf("%d",&tmp->v);
 28         return tmp;
 29     }
 30     tmp->ll=init_tree(l,(r+l)/2);
 31     tmp->rr=init_tree((r+l)/2+1,r);
 32     tmp->v =tmp->ll->v + tmp->rr->v;
 33     return tmp;
 34 }
 35 
 36 int query(int l,int r,int LL,int RR,node *t)    //查询(欲查询的左,右,区间下限,上限,根)
 37 {
 38     if(l==LL&&r==RR)    return  t->v;
 39     int mid=((LL+RR)>>1);
 40     if(t->flag) //t的孩子要改
 41     {
 42         if(t->ll)
 43         {
 44             t->ll->flag=1;
 45             t->ll->v= t->v/(LL-RR+1)*(mid-LL+1);
 46         }
 47         if(t->rr)
 48         {
 49             t->rr->flag=1;
 50             t->rr->v= t->v/(LL-RR+1)*(RR-mid);
 51         }
 52         t->flag=0;
 53     }
 54 
 55     if(l>mid)     return query(l, r, mid+1, RR, t->rr);
 56     if(r<=mid)    return query(l, r, LL, mid, t->ll);
 57     return query(l,mid,LL,mid,t->ll) + query(mid+1,r,mid+1,RR,t->rr);
 58 }
 59 
 60 void update(int l,int r,int LL,int RR,node *t)   //修改。
 61 {
 62 
 63     if(l==LL&&r==RR)
 64     {
 65         t->flag=1;
 66         t->v=(r-l+1)*W;
 67         return ;
 68     }
 69 //修改的过程中也可能遇到flag=1的情况,要进行改;
 70     int mid=((LL+RR)>>1);
 71     int tmp;
 72     if(l>mid)    update(l,r,mid+1,RR,t->rr);  //要改的在右边
 73     else if(r<=mid)    update(l,r,LL,mid,t->ll);
 74     else
 75     {
 76         update(l, mid, LL, mid, t->ll);
 77         update(mid+1, r, mid+1, RR, t->rr);
 78     }
 79     t->v=t->ll->v + t->rr->v;
 80 }
 81 
 82 
 83 int main()
 84 {
 85     freopen("input.txt", "r", stdin);
 86     cin>>n;
 87     node *tree=init_tree(1,n);
 88 
 89     cin>>q;
 90     for(int i=0; i<q; i++)
 91     {
 92         scanf("%d",&op);
 93         if(op)  //修改
 94         {
 95             scanf("%d%d%d",&a,&b,&W);
 96             update(a,b,1,n,tree);
 97         }
 98         else    //查询
 99         {
100             scanf("%d%d",&L,&R);
101             printf("%d\n",query(L,R,1,n,tree) );
102         }
103     }
104     return 0;
105 }
还没完成代码

 

hihoCoder #1078 : 线段树的区间修改

标签:

原文地址:http://www.cnblogs.com/xcw0754/p/4506910.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!