工厂

工厂

时间限制: 1 Sec  内存限制: 128 MB

题目描述

小明的叔叔是一家工厂的厂长。叔叔的工厂有n个车间,编号为1~n。
管理工厂是很麻烦的事情,特别是在多次调整机器以及员工之后,统计总生产量更是难事。
第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。
 

输出

输出 m 行。
第 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
 题解:一开始认为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 }
View Code

 

posted @ 2020-02-07 16:28  Gang_Li  阅读(584)  评论(0编辑  收藏  举报