• 工厂


    工厂

    时间限制: 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
    ",ans);
    151     }
    152     return 0;
    153 }
    View Code
  • 相关阅读:
    sass学习笔记1
    javascript 数组的深度复制
    div+css定位position详解
    滚动加载图片(懒加载)实现原理
    移动端布局经验
    js 扁平化输出数组
    axiso基本使用及python接收处理
    JSP内置对象
    JSP基本语法
    tomcat环境搭建
  • 原文地址:https://www.cnblogs.com/lglh/p/12273489.html
Copyright © 2020-2023  润新知