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

【codevs2216】行星序列 线段树 区间两异同修改+区间求和*****

时间:2015-08-05 00:43:25      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

【codevs2216】行星序列

题目描述 Description

“神州“载人飞船的发射成功让小可可非常激动,他立志长大后要成为一名宇航员假期一始,他就报名参加了“小小宇航员夏令营”,在这里小可可不仅学到了丰富的宇航知识,还参与解决了一些模拟飞行中发现的问题,今天指导老师交给他一个任务,在这次模拟飞行的路线上有N个行星,暂且称它们为一个行星序列,并将他们从1至n标号,在宇宙未知力量的作用下这N个行星的质量是不断变化的,所以他们对飞船产生的引力也会不断变化,小可可的任务就是在飞行途中计算这个行星序列中某段行星的质量和,以便能及时修正飞船的飞行线路,最终到达目的地,行星序列质量变化有两种形式:

1,行星序列中某一段行星的质量全部乘以一个值

2,行星序列中某一段行星的质量全部加上一个值

由于行星的质量和很大,所以求出某段行星的质量和后只要输出这个值模P的结果即可,小可可被这个任务难住了,聪明的你能够帮他完成这个任务吗?

输入描述 Input Description

第一行两个整数N和P(1<=p<=1000000000);

第二行含有N个非负整数,从左到右依次为a1,a2,…………,an(0<=ai<=100000000,1<=i<=n),其中ai表示第i个行星的质量:

第三行有一个整数m,表示模拟行星质量变化以及求质量和等操作的总次数。从第四行开始每行描述一个操作,输入的操作有以下三种形式:

操作1:1 t g c 表示把所有满足t<=i<=g的行星质量ai改为ai*c

操作2:2 t g c 表示把所有满足t<=i<=g的行星质量ai改为ai+c

操作3:3 t g 表示输出所有满足t<=i<=g的ai的和模p的值

其中:1<=t<=g<=N,0<=c<=10000000

注:同一行相邻的两数之间用一个空格隔开,每行开头和末尾没有多余空格

输出描述 Output Description

对每个操作3,按照它在输入中出现的顺序,依次一行输出一个整数表示所求行星质量和

样例输入 Sample Input

  7 43

1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

样例输出 Sample Output

2

35
8

数据范围及提示 Data Size & Hint

100%的数据中,M,N<=100000

40%的数据中,M,N<=10000

题解 

       这两种修改可能会造成冲突`!!!!!!

       long long 

代码

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <cstring>
  4 #include <ctime>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <set>
  8 #include <vector>
  9 #include <queue>
 10 #include <typeinfo>
 11 #include <map>
 12 #include <stack>
 13 typedef long long ll;
 14 #define inf 0x7fffffff
 15 using namespace std;
 16 inline ll read()
 17 {
 18     ll x=0,f=1;
 19     char ch=getchar();
 20     while(ch<0||ch>9)
 21     {
 22         if(ch==-)f=-1;
 23         ch=getchar();
 24     }
 25     while(ch>=0&&ch<=9)
 26     {
 27         x=x*10+ch-0;
 28         ch=getchar();
 29     }
 30     return x*f;
 31 }
 32 
 33 //**************************************************************************************
 34 
 35 struct ss
 36 {
 37     int l,r;
 38     ll sum;
 39     ll lazyc,lazyj;
 40 } tr[100000*5];
 41 int n;
 42 int p;
 43 ll a[100005];
 44 void  build(int k,int s,int t)
 45 {
 46     tr[k].l=s;
 47     tr[k].r=t;
 48     tr[k].lazyc=1;
 49     if(s==t)
 50     {
 51         tr[k].sum=a[s]%p;
 52         return;
 53     }
 54     int mid=(s+t)>>1;
 55     build(k<<1,s,mid);
 56     build(k<<1|1,mid+1,t);
 57     tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%p;
 58 }
 59 void pushdown(int k)
 60 {
 61     if(tr[k].l==tr[k].r)return;
 62     int t=tr[k].r-tr[k].l+1;
 63     ll m=tr[k].lazyc;
 64     ll a=tr[k].lazyj;
 65     tr[k<<1].sum=(tr[k<<1].sum*m+(t-(t>>1))*a)%p;
 66     tr[k<<1|1].sum=(tr[k<<1|1].sum*m+(t>>1)*a)%p;
 67     tr[k<<1].lazyj=(tr[k<<1].lazyj*m+a)%p;
 68     tr[k<<1|1].lazyj=(tr[k<<1|1].lazyj*m+a)%p;
 69     tr[k<<1].lazyc=(tr[k<<1].lazyc*m)%p;
 70     tr[k<<1|1].lazyc=tr[k<<1|1].lazyc*m%p;
 71     tr[k].lazyj=0;
 72     tr[k].lazyc=1;
 73 }
 74 void update1(int k,int s,int t,ll c)
 75 {
 76     pushdown(k);
 77     if(s==tr[k].l&&t==tr[k].r)
 78     {
 79         tr[k].sum=(tr[k].sum*c)%p;
 80         tr[k].lazyc=(tr[k].lazyc*c)%p;
 81         return;
 82     }
 83     int  mid=(tr[k].l+tr[k].r)>>1;
 84     if(t<=mid)
 85     {
 86         update1(k<<1,s,t,c);
 87     }
 88     else if(s>mid)update1(k<<1|1,s,t,c);
 89     else
 90     {
 91         update1(k<<1,s,mid,c);
 92         update1(k<<1|1,mid+1,t,c);
 93     }
 94     tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%p;
 95 }
 96 void update2(int k,int s,int t,ll c)
 97 {
 98     pushdown(k);
 99     if(s==tr[k].l&&t==tr[k].r)
100     {
101         tr[k].sum=(tr[k].sum+c*(t-s+1))%p;
102         tr[k].lazyj=(tr[k].lazyj+c)%p;
103         return;
104     }
105     int  mid=(tr[k].l+tr[k].r)>>1;
106     if(t<=mid)
107     {
108         update2(k<<1,s,t,c);
109     }
110     else if(s>mid)update2(k<<1|1,s,t,c);
111     else
112     {
113         update2(k<<1,s,mid,c);
114         update2(k<<1|1,mid+1,t,c);
115     }
116     tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%p;
117 }
118 long long ask(int k,int s,int t)
119 {
120     pushdown(k);
121     ll ans;
122     if(s==tr[k].l&&t==tr[k].r)
123     {
124         return tr[k].sum;
125     }
126     int mid=(tr[k].l+tr[k].r)>>1;
127     if(t<=mid)ans=ask(k<<1,s,t);
128     else if(s>mid) ans=ask(k<<1|1,s,t);
129     else
130     {
131         ans=(ask(k<<1,s,mid)+ask(k<<1|1,mid+1,t))%p;
132     }
133     tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%p;
134     return ans;
135 }
136 int main()
137 {
138 
139     scanf("%d%d",&n,&p);
140     for(int i=1; i<=n; i++)
141     {
142         scanf("%lld",&a[i]);
143     }
144     build(1,1,n);
145     int m;
146     scanf("%d",&m);
147     for(int i=1; i<=m; i++)
148     {
149         int t;
150         int x,y,z;
151         scanf("%d",&t);
152         if(t==1)
153         {
154             scanf("%d%d%d",&x,&y,&z);
155             update1(1,x,y,z);
156             for(int j=1; j<n; j++)
157             {
158                 printf("%d ",tr[j+7].sum);
159             }
160             /*  printf("%d\n",tr[7].sum);
161               printf("5->6lazyc:%d\n",tr[6].lazyc);
162                  printf("5->6lazyj:%d\n",tr[6].lazyj);
163                    printf("5->7lazyj:%d\n",tr[3].lazyj);*/
164         }
165         else if(t==2)
166         {
167             scanf("%d%d%d",&x,&y,&z);
168             update2(1,x,y,z);
169             for(int j=1; j<n; j++)
170             {
171                 printf("%d ",tr[j+7].sum);
172             }
173             /*  printf("%d\n",tr[7].sum);
174                printf("5->6lazyc:%d\n",tr[6].lazyc);
175                  printf("5->6lazyj:%d\n",tr[6].lazyj);
176                    printf("5->7lazyj:%d\n",tr[3].lazyj);*/
177         }
178         else
179         {
180             scanf("%d%d",&x,&y);
181             printf("%lld\n",ask(1,x,y)%p);
182             for(int j=1; j<n; j++)
183             {
184                 printf("%d ",tr[j+7].sum);
185             }
186             /*printf("%d\n",tr[7].sum);
187              printf("5->6lazyc:%d\n",tr[6].lazyc);
188                printf("5->6lazyj:%d\n",tr[6].lazyj);
189                  printf("5->7lazyj:%d\n",tr[3].lazyj);*/
190             /*  for(int i=1;i<n;i++)
191               {
192                   printf("%d ",tr[i+7].sum);
193               }
194             printf("%d\n",tr[7].sum);
195             if(i)
196             {
197                 printf("5->7:%d\n",tr[3].sum);
198                 printf("5->7lazyc:%d\n",tr[3].lazyc);
199                 printf("5->7lazyj:%d\n",tr[3].lazyj);
200             }*/
201         }
202     }
203     return 0;
204 }

 

 

【codevs2216】行星序列 线段树 区间两异同修改+区间求和*****

标签:

原文地址:http://www.cnblogs.com/zxhl/p/4703463.html

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