zoukankan      html  css  js  c++  java
  • BZOJ[4127] Abs

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4127

    不算难的样子,才见过此类模型。

    首先可以发现每次修改只增不减,那么这$O(n)$的负数最多只会有$n$次由负变正。

    所以对于每一次由负变正我们暴力在线段树上维护,每一次由负变正在线段树上会经过$O(logn)$层。

    效率$O(logn)$。

    其他的维护一下区间负数的个数什么的就可以搞了。

    一遍AC爽

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 
      5 #define l(x) ch[x][0]
      6 #define r(x) ch[x][1]
      7 #define N 100010
      8 #define LL long long
      9 #define INF 0x3f3f3f3f3f3f3f3fLL
     10 
     11 using namespace std;
     12 
     13 struct edge{
     14     int x,to;
     15 }E[N<<1];
     16 
     17 int n,m,totE;
     18 int g[N];
     19 
     20 inline int Abs(int x){
     21     if(x<0) return -x;
     22     return x;
     23 }
     24 
     25 inline void ade(int x,int y){
     26     E[++totE]=(edge){y,g[x]}; g[x]=totE;
     27 }
     28 
     29 namespace Segtree{
     30     int tot;
     31     int ch[N<<1][2];
     32     int totf[N<<1],siz[N<<1];
     33     LL maxf[N<<1],sumv[N<<1],addv[N<<1];
     34 
     35     void push(int x){
     36         if(!l(x)||!addv[x]) return;
     37         addv[l(x)]+=addv[x];
     38         sumv[l(x)]+=addv[x]*(LL)(siz[l(x)]-2*totf[l(x)]);
     39         maxf[l(x)]+=addv[x];
     40         addv[r(x)]+=addv[x];
     41         sumv[r(x)]+=addv[x]*(LL)(siz[r(x)]-2*totf[r(x)]);
     42         maxf[r(x)]+=addv[x];
     43         addv[x]=0;
     44     }
     45     
     46     void up(int x){
     47         if(!l(x)) return;
     48         sumv[x]=sumv[l(x)]+sumv[r(x)];
     49         maxf[x]=max(maxf[l(x)],maxf[r(x)]);
     50         totf[x]=totf[l(x)]+totf[r(x)];
     51     }
     52     
     53     void change(int x,int l,int r,int ql,int qr,int qv){
     54         push(x);
     55         if(ql<=l&&r<=qr&&maxf[x]+qv<0){
     56             addv[x]+=qv;
     57             sumv[x]+=qv*(LL)(siz[x]-2*totf[x]);
     58             maxf[x]+=qv;
     59         }
     60         else if(l==r){
     61             sumv[x]=qv-sumv[x];
     62             addv[x]=0;
     63             maxf[x]=-INF;
     64             totf[x]=0;
     65         }
     66         else{
     67             int mid=(l+r)>>1;
     68             if(ql<=mid) change(l(x),l,mid,ql,qr,qv);
     69             if(mid<qr)  change(r(x),mid+1,r,ql,qr,qv);
     70             up(x);
     71         }
     72     }
     73     
     74     LL ask(int x,int l,int r,int ql,int qr){
     75         push(x);
     76         if(ql<=l&&r<=qr){
     77             return sumv[x];
     78         }
     79         int mid=(l+r)>>1;
     80         LL ans=0;
     81         if(ql<=mid) ans+=ask(l(x),l,mid,ql,qr);
     82         if(mid<qr)  ans+=ask(r(x),mid+1,r,ql,qr);
     83         up(x);
     84         return ans;
     85     }
     86     
     87     int build(int src[],int l,int r){
     88         int x=++tot;
     89         siz[x]=r-l+1;
     90         if(l==r){
     91             sumv[x]=Abs(src[l]);
     92             addv[x]=0;
     93             if(src[l]>=0) maxf[x]= -INF;
     94             else maxf[x]=src[l];
     95             totf[x]= (src[l]<0) ? 1:0;
     96             return x;
     97         }
     98         int mid=(l+r)>>1;
     99         l(x)=build(src,l,mid);
    100         r(x)=build(src,mid+1,r);
    101         up(x);
    102         return x;
    103     }
    104 }
    105 
    106 #define p E[i].x
    107 
    108 int tott;
    109 int L[N],a[N],fa[N],pos[N],c[N],d[N],siz[N],h[N],top[N];
    110 bool v[N];
    111 
    112 void dfs(int x){
    113     v[x]=1; siz[x]=1; h[x]=0;
    114     for(int i=g[x];i;i=E[i].to)
    115         if(!v[p]){
    116             fa[p]=x;
    117             d[p]=d[x]+1;
    118             dfs(p);
    119             siz[x]+=siz[p];
    120             if(siz[p]>siz[h[x]])
    121                 h[x]=p;
    122         }
    123 }
    124 
    125 void cut(int x,int ft){
    126     L[x]=++tott; c[tott]=a[x]; pos[tott]=x; top[x]=ft;
    127     if(h[x]) cut(h[x],ft);
    128     for(int i=g[x];i;i=E[i].to)
    129         if(p!=fa[x]&&p!=h[x])
    130             cut(p,p);
    131 }
    132 
    133 void change(int x,int y,int v){
    134     int f1=top[x],f2=top[y];
    135     while(f1!=f2){
    136         if(d[f1]<d[f2]) swap(f1,f2),swap(x,y);
    137         Segtree::change(1,1,n,L[f1],L[x],v);
    138         x=fa[f1]; f1=top[x];
    139     }
    140     if(L[x]>L[y]) swap(x,y);
    141     Segtree::change(1,1,n,L[x],L[y],v);
    142 }
    143 
    144 LL ask(int x,int y){
    145     int f1=top[x],f2=top[y];
    146     LL ans=0;
    147     while(f1!=f2){
    148         if(d[f1]<d[f2]) swap(f1,f2),swap(x,y);
    149         ans+=Segtree::ask(1,1,n,L[f1],L[x]);
    150         x=fa[f1]; f1=top[x];
    151     }
    152     if(L[x]>L[y]) swap(x,y);
    153     ans+=Segtree::ask(1,1,n,L[x],L[y]);
    154     return ans;
    155 }
    156 
    157 int main(){
    158     scanf("%d%d",&n,&m);
    159     for(int i=1;i<=n;i++){
    160         scanf("%d",&a[i]);
    161     }
    162     int cmd,x,y;
    163     for(int i=1;i<n;i++){
    164         scanf("%d%d",&x,&y);
    165         ade(x,y); ade(y,x);
    166     }
    167     d[1]=1;
    168     dfs(1); cut(1,1);
    169     Segtree::build(c,1,n);
    170     for(int i=1;i<=m;i++){
    171         int v;
    172         scanf("%d%d%d",&cmd,&x,&y);
    173         if(cmd==1){
    174             scanf("%d",&v);
    175             change(x,y,v);
    176         }
    177         else printf("%lld
    ",ask(x,y));
    178     }
    179     return 0;
    180 }
    View Code
  • 相关阅读:
    Flutter移动电商实战 --(40)路由_Fluro的全局注入和使用方法
    Flutter移动电商实战 --(39)路由_Fluro的路由配置和静态化
    Flutter移动电商实战 --(38)路由_Fluro中Handler编写方法
    Flutter移动电商实战 --(37)路由_Fluro引入和商品详细页建立
    网络基础:NetBIOS
    linux 定时任务
    linux useradd 命令基本用法
    Git undo 操作
    Git 查看文件的历史
    Ubuntu14.04安装postgresql9.4
  • 原文地址:https://www.cnblogs.com/lawyer/p/4592349.html
Copyright © 2011-2022 走看看