码迷,mamicode.com
首页 > 其他好文 > 详细

ZJOI 2018 历史

时间:2018-04-20 23:34:31      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:bool   sign   read   push   etc   oid   else   std   access   

SOL:

   LCT 模拟一下就好啦啦啦啦啦啦啦啦啦啦啦啦。

#include<bits/stdc++.h>
#define LL long long
#define eho(x) for(int i=head[x];i;i=net[i])
#define v fall[i]
#define N 400007
//#define int LL
#define sight(x) (‘0‘<=x&&x<=‘9‘)
#define l(x) ch[x][0]
#define r(x) ch[x][1]
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
int fall[N<<1],net[N<<1],head[N],tot,mi[N],n,m,x,y;
LL ans,siz[N],ft[N],a[N],laz[N];
int ch[N][2],f[N],son[N],q[N],top;
template <class T>
inline void read(T &x){
    static char c;
    for (c=getchar();!sight(c);c=getchar());
    for (x=0;sight(c);c=getchar())x=x*10+c-48;
}
void write(LL x){if (x<10) {putchar(0+x); return;} write(x/10); putchar(0+x%10);}
inline void writeln(LL x){ if (x<0) putchar(-),x*=-1; write(x); putchar(\n); }
inline void writel(LL x){ if (x<0) putchar(-),x*=-1; write(x); putchar( ); }
inline bool rt(int x){
    return l(f[x])!=x&&r(f[x])!=x;
}
inline void push_down(int x){
    laz[l(x)]+=laz[x]; siz[l(x)]+=laz[x];
    laz[r(x)]+=laz[x]; siz[r(x)]+=laz[x];
    laz[x]=0; 
}
inline void push_up(int x){
    ans-=ft[x]; 
    ft[x]=min(siz[x]-1,2*(siz[x]-a[x]));
    if (son[x]) ft[x]=siz[x]-siz[son[x]]<<1;
    ans+=ft[x];
}
inline void ro(int x){
    int y=f[x],z=f[y],kind=(l(y)==x);
    if (!rt(y)) ch[z][ch[z][1]==y]=x;
    f[ch[x][kind]]=y; f[y]=x; f[x]=z;
    ch[y][kind^1]=ch[x][kind]; ch[x][kind]=y;
} 
inline void splay(int x) {
    q[top=1]=x;
    for (int i=x;!rt(i);i=f[i]) q[++top]=f[i];
    while (top) push_down(q[top--]);
    int y,z;
    while (!rt(x)) {
        y=f[x],z=f[y];
        if (!rt(y)) 
            if (ch[z][0]==y^ch[y][0]==x) ro(x); else ro(y);
        ro(x);
    }
}
inline void add(int x,int y) {
    fall[++tot]=y; net[tot]=head[x]; head[x]=tot;
}
void dfs(int x,int fa){
    f[x]=fa; siz[x]=a[x]; mi[x]=a[x];
    eho(x) if(v^fa) dfs(v,x),siz[x]+=siz[v];
    eho(x) if (v^fa&&siz[x]<2*siz[v]) son[x]=v,ch[x][1]=v;
    push_up(x);
}
void access(int x,int y) {
    int t=0;a[x]+=y;
    while (x) {
        splay(x);
        siz[x]+=y; siz[l(x)]+=y; laz[l(x)]+=y;
        if (son[x]) {
            splay(son[x]),splay(x);
            if (siz[son[x]]*2<=siz[x]) son[x]=ch[x][1]=0;
        }
        if (t) {
            while (l(t)) t=l(t);
            splay(t);
            if (siz[t]*2>siz[x]) son[x]=t,r(x)=t;
        }
        push_up(x); t=x; x=f[x];
    }
}
signed main () {
    read(n); read(m);
    for (int i=1;i<=n;i++) read(a[i]);
    for (int i=1;i<n;i++) {
        read(x),read(y),add(x,y),add(y,x);
    }
    ans=0;
    dfs(1,0);
    writeln(ans);
    while (m--) {
        read(x); read(y);
        access(x,y);
        writeln(ans);
    }
}

 

ZJOI 2018 历史

标签:bool   sign   read   push   etc   oid   else   std   access   

原文地址:https://www.cnblogs.com/rrsb/p/8893699.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!