工厂
工厂
时间限制: 1 Sec 内存限制: 128 MB
题目描述
小明的叔叔是一家工厂的厂长。叔叔的工厂有n个车间,编号为1~n。
管理工厂是很麻烦的事情,特别是在多次调整机器以及员工之后,统计总生产量更是难事。
第i个车间在刚开始的时候机器生产力为ai,有bi个员工,那么这个车间的生产力就为ai*bi。
工厂的总生产力定义为所有车间的生产力之和。
接下来的m天,每天叔叔就会调整一段区间的车间。
有两种调整:
第一种,是对于一段区间[l,r]的每一个车间重新分配每个车间的工人数为x。
第二种,是对于一段区间[l,r]的每一个车间增加机器生产力x。
现在,小明的叔叔想知道每天调整之后工厂的生产量变为多少。
管理工厂是很麻烦的事情,特别是在多次调整机器以及员工之后,统计总生产量更是难事。
第i个车间在刚开始的时候机器生产力为ai,有bi个员工,那么这个车间的生产力就为ai*bi。
工厂的总生产力定义为所有车间的生产力之和。
接下来的m天,每天叔叔就会调整一段区间的车间。
有两种调整:
第一种,是对于一段区间[l,r]的每一个车间重新分配每个车间的工人数为x。
第二种,是对于一段区间[l,r]的每一个车间增加机器生产力x。
现在,小明的叔叔想知道每天调整之后工厂的生产量变为多少。
输入
第一行两个整数 n 和 m,表示车场数以及天数。
接下来 n 行,每行描述一个车间。
第 i+1 行描述第 i 个车间,包括两个整数 ai 和 bi,意义如题目所述。
接下来 m 行,每一行表示一个修改操作。
Set l r x 表示对于一段区间[l,r]的每一个车间重新分配每个车间的工人数为 x。
Add l r x 表示对于一段区间[l,r]的每一个车间增加机器生产力 x。
接下来 n 行,每行描述一个车间。
第 i+1 行描述第 i 个车间,包括两个整数 ai 和 bi,意义如题目所述。
接下来 m 行,每一行表示一个修改操作。
Set l r x 表示对于一段区间[l,r]的每一个车间重新分配每个车间的工人数为 x。
Add l r x 表示对于一段区间[l,r]的每一个车间增加机器生产力 x。
输出
输出 m 行。
第 i 行表示第 i 天调整后,工厂的总生产力。
第 i 行表示第 i 天调整后,工厂的总生产力。
样例输入 Copy
4 4
2 1
4 3
6 5
8 7
Set 1 3 2
Add 2 3 1
Add 3 3 2
Set 1 4 2
样例输出 Copy
80
84
88
48
提示
20%的数据,1<=n,m<=2000
100%的数据,1<=n,m<=100000,1<=l<=r<=n,1<=x<=10000
View Code
100%的数据,1<=n,m<=100000,1<=l<=r<=n,1<=x<=10000
题解:一开始认为Set操作没法这样暴力,但最终还是过了!
AC代码:
1 #pragma GCC optimize(3) 2 #include <bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=1e5+50; 6 char op[maxn]; 7 ll a[maxn],b[maxn],ans; 8 int n,m; 9 ll suma[maxn*4],sumb[maxn*4],la[maxn*4],lb[maxn*4]; 10 /*a*/ 11 void builda(int l,int r,int rt) 12 { 13 if(l==r){ 14 suma[rt]=a[l]; 15 return ; 16 } 17 int mid=(l+r)/2; 18 builda(l,mid,2*rt); 19 builda(mid+1,r,2*rt+1); 20 suma[rt]=suma[2*rt]+suma[2*rt+1]; 21 } 22 ll querya(int L,int R,int l,int r,int rt) 23 { 24 if(L<=l && r<=R){ 25 return suma[rt]; 26 } 27 int mid=(l+r)/2; 28 if(la[rt]>0){ 29 la[2*rt]+=la[rt]; 30 suma[2*rt]+=la[rt]*(mid-l+1); 31 la[2*rt+1]+=la[rt]; 32 suma[2*rt+1]+=la[rt]*(r-mid-1+1); 33 la[rt]=0; 34 } 35 ll res=0,ret=0; 36 if(L<=mid) res=querya(L,R,l,mid,2*rt); 37 if(R>=mid+1) ret=querya(L,R,mid+1,r,2*rt+1); 38 return res+ret; 39 } 40 void updatea(int L,int R,int l,int r,int rt,ll val) 41 { 42 if(L<=l && r<=R){ 43 la[rt]+=val; 44 suma[rt]+=val*(r-l+1); 45 return ; 46 } 47 int mid=(l+r)/2; 48 if(la[rt]>0){ 49 la[2*rt]+=la[rt]; 50 suma[2*rt]+=la[rt]*(mid-l+1); 51 la[2*rt+1]+=la[rt]; 52 suma[2*rt+1]+=la[rt]*(r-mid-1+1); 53 la[rt]=0; 54 } 55 if(L<=mid) updatea(L,R,l,mid,2*rt,val); 56 if(R>=mid+1) updatea(L,R,mid+1,r,2*rt+1,val); 57 suma[rt]=suma[2*rt]+suma[2*rt+1]; 58 } 59 /*b*/ 60 void buildb(int l,int r,int rt) 61 { 62 if(l==r){ 63 sumb[rt]=b[l]; 64 lb[rt]=b[l]; 65 return ; 66 } 67 int mid=(l+r)/2; 68 buildb(l,mid,2*rt); 69 buildb(mid+1,r,2*rt+1); 70 sumb[rt]=sumb[2*rt]+sumb[2*rt+1]; 71 } 72 ll queryb(int L,int R,int l,int r,int rt) 73 { 74 if(L<=l && r<=R){ 75 return sumb[rt]; 76 } 77 int mid=(l+r)/2; 78 if(lb[rt]>0){ 79 lb[2*rt]=lb[rt]; 80 sumb[2*rt]=(mid-l+1)*lb[rt]; 81 lb[2*rt+1]=lb[rt]; 82 sumb[2*rt+1]=(r-mid-1+1)*lb[rt]; 83 lb[rt]=0; 84 } 85 ll res=0,ret=0; 86 if(L<=mid) res=queryb(L,R,l,mid,2*rt); 87 if(R>=mid+1) ret=queryb(L,R,mid+1,r,2*rt+1); 88 return res+ret; 89 } 90 void updateb(int L,int R,int l,int r,int rt,ll val) 91 { 92 if(L<=l && r<=R){ 93 lb[rt]=val; 94 sumb[rt]=val*(r-l+1); 95 return ; 96 } 97 int mid=(l+r)/2; 98 if(lb[rt]>0){ 99 lb[2*rt]=lb[rt]; 100 sumb[2*rt]=(mid-l+1)*lb[rt]; 101 lb[2*rt+1]=lb[rt]; 102 sumb[2*rt+1]=(r-mid-1+1)*lb[rt]; 103 lb[rt]=0; 104 } 105 if(L<=mid) updateb(L,R,l,mid,2*rt,val); 106 if(R>=mid+1) updateb(L,R,mid+1,r,2*rt+1,val); 107 sumb[rt]=sumb[2*rt]+sumb[2*rt+1]; 108 } 109 void handle(int L,int R,int l,int r,int rt)//减掉原区间的贡献(感觉有点暴力~) 110 { 111 if(L<=l && r<=R){ 112 if(lb[rt]>0){ 113 ans-=lb[rt]*querya(l,r,1,n,1); 114 return ; 115 } 116 } 117 int mid=(l+r)/2; 118 if(lb[rt]>0){ 119 lb[2*rt]=lb[rt]; 120 sumb[2*rt]=(mid-l+1)*lb[rt]; 121 lb[2*rt+1]=lb[rt]; 122 sumb[2*rt+1]=(r-mid-1+1)*lb[rt]; 123 lb[rt]=0; 124 } 125 if(L<=mid) handle(L,R,l,mid,2*rt); 126 if(R>=mid+1) handle(L,R,mid+1,r,2*rt+1); 127 } 128 int main() 129 { 130 scanf("%d %d",&n,&m); 131 for(int i=1;i<=n;i++){ 132 scanf("%lld %lld",&a[i],&b[i]); 133 ans+=a[i]*b[i]; 134 } 135 builda(1,n,1); 136 buildb(1,n,1); 137 while(m--){ 138 int l,r;ll x; 139 scanf("%s %d %d %lld",op,&l,&r,&x); 140 if(strcmp(op,"Add")==0){ 141 ll cnt=queryb(l,r,1,n,1); 142 ans+=cnt*x; 143 updatea(l,r,1,n,1,x); 144 } 145 else{ 146 handle(l,r,1,n,1); 147 ans+=x*querya(l,r,1,n,1); 148 updateb(l,r,1,n,1,x); 149 } 150 printf("%lld\n",ans); 151 } 152 return 0; 153 }