zoukankan      html  css  js  c++  java
  • [bzoj4127]Abs

    先树链剖分,开一棵线段树维护区间:1.abs的和;2.正数的数量-负数的数量;3.最大的负数。

    询问就可以直接处理,考虑修改操作,对于一个区间,如果最大的负数+d变为了正数,就暴力修改下去,否则直接修改13两个信息并打上懒标记。因为d是非负的,所以每一个节点最多修改一次,时间复杂度不变。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 100005
      4 #define mid (l+r>>1)
      5 #define L (k<<1)
      6 #define R (L+1)
      7 #define ll long long
      8 struct ji{
      9     int nex,to;
     10 }edge[N<<1];
     11 int E,V,n,m,p,x,y,z,w[N],head[N],fa[N],sh[N],sz[N],ma[N],top[N],id[N],id2[N],zf[N<<2],mf[N<<2];
     12 ll f[N<<2],laz[N<<2];
     13 void add(int x,int y){
     14     edge[E].nex=head[x];
     15     edge[E].to=y;
     16     head[x]=E++;
     17 }
     18 void update(int k,ll p){
     19     mf[k]+=p;
     20     f[k]+=p*zf[k];
     21     laz[k]+=p;
     22 }
     23 void up(int k){
     24     mf[k]=max(mf[L],mf[R])+laz[k];
     25     f[k]=f[L]+f[R]+laz[k]*zf[k];
     26     zf[k]=zf[L]+zf[R];
     27 }
     28 void down(int k){
     29     update(L,laz[k]);
     30     update(R,laz[k]);
     31     laz[k]=0;
     32 }
     33 void build(int k,ll p){
     34     f[k]=abs(p);
     35     zf[k]=2*(p>0)-1;
     36     if (p>0)mf[k]=-0x3f3f3f3f;
     37     else mf[k]=p;
     38 }
     39 void build(int k,int l,int r){
     40     if (l==r){
     41         build(k,w[id2[l]]);
     42         return;
     43     }
     44     build(L,l,mid);
     45     build(R,mid+1,r);
     46     up(k);
     47 }
     48 void update(int k,int l,int r,int x,int y,int z){
     49     if ((l>y)||(x>r))return;
     50     if (l==r){
     51         build(k,f[k]*zf[k]+z);
     52         return;
     53     }
     54     if ((x<=l)&&(r<=y)&&(mf[k]+z<=0)){
     55         update(k,z);
     56         return;
     57     }
     58     down(k);
     59     update(L,l,mid,x,y,z);
     60     update(R,mid+1,r,x,y,z);
     61     up(k);
     62 }
     63 ll query(int k,int l,int r,int x,int y){
     64     if ((x>r)||(l>y))return 0;
     65     if ((x<=l)&&(r<=y))return f[k];
     66     down(k);
     67     return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
     68 }
     69 void dfs(int k,int f,int s){
     70     fa[k]=f;
     71     sz[k]=1;
     72     sh[k]=s;
     73     for(int i=head[k];i!=-1;i=edge[i].nex)
     74         if (edge[i].to!=f){
     75             dfs(edge[i].to,k,s+1);
     76             sz[k]+=sz[edge[i].to];
     77             if (sz[ma[k]]<sz[edge[i].to])ma[k]=edge[i].to;
     78         }
     79 }
     80 void dfs2(int k,int t){
     81     id[k]=++x;
     82     id2[x]=k;
     83     top[k]=t;
     84     if (ma[k])dfs2(ma[k],t);
     85     for(int i=head[k];i!=-1;i=edge[i].nex)
     86         if ((edge[i].to!=fa[k])&&(edge[i].to!=ma[k]))dfs2(edge[i].to,edge[i].to);
     87 }
     88 ll calc(int x,int y){
     89     ll ans=0;
     90     while (top[x]!=top[y]){
     91         if (sh[top[x]]<sh[top[y]])swap(x,y);
     92         ans+=query(1,1,n,id[top[x]],id[x]);
     93         x=fa[top[x]];
     94     }
     95     if (sh[x]>sh[y])swap(x,y);
     96     return ans+query(1,1,n,id[x],id[y]);
     97 }
     98 void update(int x,int y,int z){
     99     while (top[x]!=top[y]){
    100         if (sh[top[x]]<sh[top[y]])swap(x,y);
    101         update(1,1,n,id[top[x]],id[x],z);
    102         x=fa[top[x]];
    103     }
    104     if (sh[x]>sh[y])swap(x,y);
    105     update(1,1,n,id[x],id[y],z);
    106 }
    107 int main(){
    108     scanf("%d%d",&n,&m);
    109     memset(head,-1,sizeof(head));
    110     for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    111     for(int i=1;i<n;i++){
    112         scanf("%d%d",&x,&y);
    113         add(x,y);
    114         add(y,x);
    115     }
    116     dfs(1,1,0);
    117     x=0;
    118     dfs2(1,1);
    119     build(1,1,n);
    120     for(int i=1;i<=m;i++){
    121         scanf("%d%d%d",&p,&x,&y);
    122         if (p==2)printf("%lld\n",calc(x,y));
    123         else{
    124             scanf("%d",&z);
    125             update(x,y,z);
    126         }
    127     }
    128 }
    View Code
  • 相关阅读:
    React 组件间的通讯
    javascript 闭包详解及作用
    selenium使用技巧
    多线程
    渗透测试
    什么是Selenium Grid?如何搭建Selenium Grid?
    前端性能测试工具原理与行业常用工具简介
    后端性能测试工具原理与行业常用工具简介
    性能测试方法和应用
    软件性能与性能指标
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249927.html
Copyright © 2011-2022 走看看