【codevs2216】行星序列 线段树 区间两异同修改+区间求和*****
【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
样例输出 Sample Output
2
数据范围及提示 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 }