• [bzoj4127] Abs


      链剖。线段树要记录区间内负数的个数,负数的最大值..

      如果增加后能使负数变正的话就往下暴力更新。。。

      时间复杂度O(nlog^2n)

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #define ll long long
      7 using namespace std;
      8 const int maxn=100233;
      9 struct zs{
     10     int too,pre;
     11 }e[maxn<<1];int tot1,last[maxn];
     12 int lc[maxn<<1],rc[maxn<<1],sz[maxn<<1],mx[maxn<<1],num[maxn<<1],tot;
     13 ll sm[maxn<<1],add[maxn<<1],V,SM;
     14 int dfn[maxn],tim,st[maxn],top,pos[maxn],bel[maxn],v[maxn],sz1[maxn],dep[maxn],fa[maxn],len[maxn],rt[maxn];
     15 int i,j,k,n,m,L,R;
     16  
     17 int ra,fh;char rx;
     18 inline int read(){
     19     rx=getchar(),ra=0,fh=1;
     20     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
     21     if(rx=='-')fh=-1,rx=getchar();
     22     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
     23 }
     24  
     25  
     26 inline void upd(int x){
     27     int l=lc[x],r=rc[x];
     28     if(mx[l]==-1e9)mx[x]=mx[r]+add[r];else
     29     if(mx[r]==-1e9)mx[x]=mx[l]+add[l];else mx[x]=max(mx[l]+add[l],mx[r]+add[r]);
     30     if(mx[x]>=0)mx[x]=-1e9;
     31     sm[x]=sm[l]+sm[r],num[x]=num[l]+num[r];
     32 }
     33 inline void pushdown(int x){
     34     int l=lc[x],r=rc[x];
     35     if(mx[l]==-1e9)sm[l]+=add[x]*sz[l];
     36     else sm[l]+=add[x]*(sz[l]-num[l]-num[l]);
     37     if(mx[r]==-1e9)sm[r]+=add[x]*sz[r];
     38     else sm[r]+=add[x]*(sz[r]-num[r]-num[r]);
     39     add[l]+=add[x],add[r]+=add[x],
     40     add[x]=0;
     41 }
     42 void build(int a,int b){
     43     int x=++tot;sz[x]=b-a+1;
     44     if(a==b){
     45         sm[x]=abs(v[st[a]]);
     46         if(v[st[a]]<0)mx[x]=v[st[a]],num[x]=1;else mx[x]=-1e9;
     47         return;
     48     }
     49     int mid=a+b>>1;
     50     lc[x]=tot+1,build(a,mid),rc[x]=tot+1,build(mid+1,b);
     51     upd(x);
     52 //  printf("  %d--%d sm:%lld mx:%d
    ",a,b,sm[x],mx[x]);
     53 }
     54 void insert(int x,int a,int b){
     55     if(L<=a&&R>=b){
     56         if(mx[x]==-1e9){sm[x]+=V*sz[x],add[x]+=V;return;}
     57         if(mx[x]+add[x]+V<0){sm[x]+=V*(sz[x]-num[x]-num[x]),add[x]+=V;return;}
     58     }
     59      
     60     if(a==b){
     61 //      printf("! %d %d
    ",a,mx[x]);
     62         if(mx[x]+add[x]+V>=0)sm[x]=mx[x]+add[x]+V,mx[x]=-1e9,add[x]=num[x]=0;
     63         else add[x]+=V,sm[x]-=V;
     64 //      printf("  %d %lld
    ",mx[x],sm[x]);
     65         return;
     66     }
     67     if(add[x])pushdown(x);
     68     int mid=a+b>>1;
     69     if(L<=mid)insert(lc[x],a,mid);
     70     if(R>mid)insert(rc[x],mid+1,b);
     71     upd(x);
     72 //  printf("ins:  %d--%d  sm:%lld mx:%d  num:%d
    ",a,b,sm[x],mx[x],num[x]);
     73 }
     74 void query(int x,int a,int b){
     75     if(L<=a&&R>=b){SM+=sm[x];/*printf("%d--%d    %lld
    ",a,b,sm[x]);*/return;}
     76     if(add[x])pushdown(x);
     77     int mid=a+b>>1;
     78     if(L<=mid)query(lc[x],a,mid);
     79     if(R>mid)query(rc[x],mid+1,b);
     80     upd(x);
     81 }
     82  
     83 void dfs(int x){
     84     sz1[x]=1,dep[x]=dep[fa[x]]+1;
     85     for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x])
     86         fa[e[i].too]=x,dfs(e[i].too),sz1[x]+=sz1[e[i].too];
     87 }
     88 void dfs2(int x,int chain){
     89     int mx=0,i;
     90     dfn[x]=++tim,pos[x]=tim-dfn[chain]+1,
     91     bel[x]=chain,st[++top]=x;
     92     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&sz1[e[i].too]>sz1[mx])mx=e[i].too;
     93     if(!mx){
     94         len[chain]=pos[x],rt[chain]=tot+1,build(1,top),top=0;
     95         return;
     96     }else dfs2(mx,chain);
     97     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=mx)dfs2(e[i].too,e[i].too);
     98 }
     99 inline int getlca(int a,int b){
    100     if(dep[bel[a]]<dep[bel[b]])swap(a,b);
    101     while(bel[a]!=bel[b]){
    102         a=fa[bel[a]];
    103         if(dep[bel[a]]<dep[bel[b]])swap(a,b);
    104     }
    105     return dep[a]<dep[b]?a:b;
    106 }
    107  
    108 void change(int a,int lca){
    109     while(bel[a]!=bel[lca]){
    110         L=1,R=pos[a],insert(rt[bel[a]],1,len[bel[a]]);
    111         a=fa[bel[a]];
    112     }
    113     if(a!=lca)L=pos[lca]+1,R=pos[a],insert(rt[bel[a]],1,len[bel[a]]);
    114 }
    115 void query1(int a,int lca){//printf("Q %d %d
    ",a,lca);
    116     while(bel[a]!=bel[lca]){
    117         L=1,R=pos[a],query(rt[bel[a]],1,len[bel[a]]);
    118         a=fa[bel[a]];
    119     }
    120     if(a!=lca)L=pos[lca]+1,R=pos[a],/*printf("L R:  %d %d
    ",L,R),*/query(rt[bel[a]],1,len[bel[a]]);
    121 }
    122 inline void insert(int a,int b){
    123     e[++tot1].too=b,e[tot1].pre=last[a],last[a]=tot1;
    124     e[++tot1].too=a,e[tot1].pre=last[b],last[b]=tot1;
    125 }
    126 int main(){
    127     n=read(),m=read();
    128     for(i=1;i<=n;i++)v[i]=read();
    129     for(i=1;i<n;i++)insert(read(),read());
    130     dfs(1),dfs2(1,1);int id,lca,a,b;
    131 //  for(i=1;i<=n;i++)printf("%d  bel:%d
    ",i,bel[i]);//return 233;
    132     while(m--){
    133         id=read(),a=read(),b=read(),lca=getlca(a,b);
    134         if(id==1){
    135             V=read();
    136             if(!V)continue;
    137             change(a,lca),change(b,lca);
    138             L=R=pos[lca],insert(rt[bel[lca]],1,len[bel[lca]]);
    139         }else{
    140             SM=0;
    141             query1(a,lca),query1(b,lca),
    142             L=R=pos[lca],query(rt[bel[lca]],1,len[bel[lca]]);
    143             printf("%lld
    ",SM);
    144         }//puts("");
    145     }
    146     return 0;
    147 }
    View Code
  • 相关阅读:
    大数据平台的数据源
    大数据平台的数据采集
    kubernetes入门
    机器学习分类算法
    唱吧DevOps的落地,微服务CI/CD的范本技术解读
    JavaEE开发之SpringBoot整合MyBatis以及Thymeleaf模板引擎
    MySQL索引及查询优化总结 专题
    玩转spring boot——ajax跨域
    Linux Shell远程执行命令(命令行与脚本方式)
    Android ServiceConnection
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5597866.html
Copyright © 2020-2023  润新知