zoukankan      html  css  js  c++  java
  • CodeForces Round #179 (295A)

        线段树的区间更新与区间求和...一颗这样的线段树用两次...

        先扫描1~k...用线段树统计出每个操作执行的次数...

        那么每个操作就变成了 op. l  , op.r , op.c= times* op.c

        清空线段树..将初始的a1,a2~~an放入..用每个操作来更新值~~


    Program:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<set>
    #include <ctime>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #define oo 1000000007
    #define ll long long
    #define pi acos(-1.0)
    #define MAXN 100005
    using namespace std;    
    struct node
    {
          ll l,r,c;
    }op[MAXN];
    ll sum[MAXN<<2],col[MAXN<<2],a[MAXN];
    int n,m,k;
    void PushDown(ll len,int now)
    {
          if (!col[now]) return;
          col[now<<1]+=col[now];
          col[(now<<1)|1]+=col[now];
          sum[now<<1]+=col[now]*(len-(len>>1));
          sum[(now<<1)|1]+=col[now]*(len>>1);
          col[now]=0;
          return;
    }
    void update(int L,int R,ll c,int l,int r,int now)
    {
          if (L<=l && R>=r)
          {
                 sum[now]+=(r-l+1)*c;
                 col[now]+=c;
                 return;
          }
          int mid=(l+r)/2;
          PushDown(r-l+1,now);
          if (L<=mid) update(L,R,c,l,mid,now<<1);
          if (R>mid)  update(L,R,c,mid+1,r,(now<<1)|1);
          sum[now]=sum[now<<1]+sum[(now<<1)|1];
          return;
    } 
    ll query(int L,int R,int l,int r,int now)
    {
          ll ans=0;
          if (L<=l && R>=r) return sum[now];
          int mid=(l+r)/2;
          PushDown(r-l+1,now);
          if (L<=mid) ans+=query(L,R,l,mid,now<<1);
          if (R>mid)  ans+=query(L,R,mid+1,r,(now<<1)|1);      
          return ans;
    }
    int main()
    {  
          int i; 
          while (~scanf("%d%d%d",&n,&m,&k))
          {
                 memset(sum,0,sizeof(sum));
                 memset(col,0,sizeof(col));
                 for (i=1;i<=n;i++) scanf("%I64d",&a[i]);
                 for (i=1;i<=m;i++) scanf("%I64d%I64d%I64d",&op[i].l,&op[i].r,&op[i].c);
                 for (i=1;i<=k;i++)
                 {
                         int x,y;
                         scanf("%d%d",&x,&y);
                         update(x,y,1,1,m,1);
                 } 
                 for (i=1;i<=m;i++)
                 { 
                         ll x;
                         x=query(i,i,1,m,1);
                         op[i].c*=x;
                 }
                 memset(sum,0,sizeof(sum));
                 memset(col,0,sizeof(col));
                 for (i=1;i<=n;i++) update(i,i,a[i],1,n,1);
                 for (i=1;i<=m;i++) update(op[i].l,op[i].r,op[i].c,1,n,1);
                 for (i=1;i<=n;i++) printf("%I64d ",query(i,i,1,n,1));
                 printf("
    ");
          }
          return 0;
    }
    


  • 相关阅读:
    python中字典一键多相同值反转技巧
    win10下安装mysql
    上台阶问题的具体走法用python来实现
    桥接模式
    适配器模式
    多线程中lock的使用
    原型模式
    多线程
    建造者模式
    代理模式
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3211859.html
Copyright © 2011-2022 走看看