noip模拟46
A. 数数
签到题.
A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long int
#define ull unsigend ll
#define re register ll
#define lf double
#define lbt(x) (x&(-x))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
inline ll read() {
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
const ll N=3e5+51;
ll m,n,minn,maxn;
ll w[N];
struct I { ll minn,maxn,num; } tr[N<<4];
inline void Init(){
n=read(); minn=1e7,maxn=-1e7;
for(re i=1;i<=n;++i)
w[i]=read(),minn=min(minn,w[i]);
if(minn<=0){
for(re i=1;i<=n;++i)
w[i]+=abs(minn)+1,maxn=max(maxn,w[i]);
}
else{
for(re i=1;i<=n;++i) maxn=max(maxn,w[i]);
}
return ;
}
inline void pushup(ll x){
tr[x].num=tr[x<<1].num+tr[x<<1|1].num,
tr[x].minn=min(tr[x<<1].minn,tr[x<<1|1].minn),
tr[x].maxn=max(tr[x<<1].maxn,tr[x<<1|1].maxn);
return ;
}
void update(ll x,ll l,ll r,ll pos,ll num){
if(l==r){
tr[x].num+=num;
if(tr[x].num) tr[x].minn=l,tr[x].maxn=l;
else tr[x].minn=1e7,tr[x].maxn=-1;
return ;
}
ll mid=(l+r)>>1;
if(pos<=mid) update(x<<1,l,mid,pos,num);
else update(x<<1|1,mid+1,r,pos,num);
pushup(x); return ;
}
void build(ll x,ll l,ll r){
if(l==r){
tr[x].minn=1e7,tr[x].maxn=-1;
return ;
}
ll mid=(l+r)>>1;
build(x<<1,l,mid),build(x<<1|1,mid+1,r);
pushup(x); return ;
}
inline void Work(){
build(1,1,maxn);
for(re i=1;i<=n;++i) update(1,1,maxn,w[i],1);
puts("0"); ll x,y,ans=0,res=0;
for(re i=2;i<=n-1;i+=2){
x=tr[1].minn,y=tr[1].maxn;
update(1,1,maxn,x,-1),update(1,1,maxn,y,-1);
printf("%lld\n%lld\n",abs(y-x)+ans+res,2*abs(y-x)+2*res+ans);
ans+=((abs(y-x)+res)<<1),res+=abs(y-x);
}
x=tr[1].minn,y=tr[1].maxn;
if((n&1)^1) printf("%lld\n",ans+res+abs(y-x));
return ;
}
signed main(){
Init();
Work();
exit(0);
}
B. 数树
C. 鼠树
发现这个题实现起来很复杂,
权值转移地很频繁,
所以可以把权值存得更间接、简洁一些.
因为想学线段树分裂,所以这里打的是线段树分裂.
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll unsigned int
#define re register ll
#define lf double
#define lbt(x) (x&(-x))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
inline ll read() {
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
const ll N=6e5+51;
ll n,m,ops,cnt,now,ts;
ll rt[N],dfn[N],siz[N],rk[N],son[N],fa[N],top[N],dep[N],head[N];
struct I { ll u,v,nxt; } e[N];
set<ll> s;
inline void add(ll u,ll v){
e[++ts].u=u,e[ts].v=v,e[ts].nxt=head[u],
head[u]=ts;
}
struct Tree_Array {
ll res,tmp; ll a[N<<3],b[N<<3],c[N<<3];
inline void update1(ll x,ll w){ for(;x<=n;x+=lbt(x)) a[x]+=w; }
inline void update2(ll x,ll w){ tmp=x*w; for(;x<=n;x+=lbt(x)) b[x]+=w,c[x]+=tmp; }
inline ll query1(ll x){ res=0,tmp=x; for(;x;x&=x-1) res+=a[x],res+=(tmp+1)*b[x],res-=c[x]; return res; }
inline ll query2(ll x){ res=0,tmp=x; for(;x;x&=x-1) res+=(tmp+1)*b[x],res-=c[x]; return res; }
} A;
struct Segment {
ll tot,tail; ll skt[N<<3];
struct II { ll w,ls,rs,lzy,sz; } tr[N<<3];
inline void reg(ll &x){ skt[++tail]=x,x=0; }
inline void get(ll &x){ x=(tail?skt[tail--]:++tot); tr[x].w=0,tr[x].ls=0,tr[x].rs=0,tr[x].lzy=0; }
inline void pushup(ll x){ tr[x].w=tr[tr[x].ls].w+tr[tr[x].rs].w,tr[x].sz=tr[tr[x].ls].sz+tr[tr[x].rs].sz; }
inline void spread(ll x){
if(!tr[x].lzy) return ;
ll ls=tr[x].ls,rs=tr[x].rs,&lzy=tr[x].lzy;
tr[ls].w+=lzy*tr[ls].sz,tr[rs].w+=lzy*tr[rs].sz,tr[ls].lzy+=lzy,tr[rs].lzy+=lzy,lzy=0;
}
void build(ll &x,ll l,ll r){
get(x); tr[x].sz=(r-l+1);
if(l==r) return ; ll mid=(l+r)>>1;
build(tr[x].ls,l,mid),build(tr[x].rs,mid+1,r);
}
void merge(ll &x,ll &y,ll l,ll r){
if((!x) or (!y)) return x=x+y,void();
spread(x),spread(y);ll mid=(l+r)>>1;
merge(tr[x].ls,tr[y].ls,l,mid),merge(tr[x].rs,tr[y].rs,mid+1,r);
pushup(x); reg(y);
}
void split(ll &x,ll &y,ll l,ll r,ll ql,ll qr){
if(!x) return ;
if(l>=ql and r<=qr) return y=x,x=0,void();
get(y); spread(x); ll mid=(l+r)>>1;
if(ql<=mid) split(tr[x].ls,tr[y].ls,l,mid,ql,qr);
if(qr>mid) split(tr[x].rs,tr[y].rs,mid+1,r,ql,qr);
pushup(x),pushup(y); if(!tr[x].sz) reg(x);
}
void update(ll x,ll l,ll r,ll ql,ll qr,ll w){
if(!x) return;
if(l>=ql and r<=qr) return tr[x].w+=tr[x].sz*w,tr[x].lzy+=w,A.update1(dfn[now],tr[x].sz*w),void();
spread(x);ll mid=(l+r)>>1;
if(ql<=mid) update(tr[x].ls,l,mid,ql,qr,w);
if(qr>mid) update(tr[x].rs,mid+1,r,ql,qr,w);
pushup(x);
}
ll query(ll x,ll l,ll r,ll ql,ll qr){
if(!x) return 0; if(l>=ql and r<=qr) return tr[x].w;
spread(x); ll res=0; ll mid=(l+r)>>1;
if(ql<=mid) res+=query(tr[x].ls,l,mid,ql,qr);
if(qr>mid) res+=query(tr[x].rs,mid+1,r,ql,qr);
pushup(x); return res;
}
} B;
void dfs1(ll u,ll dad,ll depth){
dep[u]=depth,fa[u]=dad,siz[u]=1;
for(re i=head[u];i;i=e[i].nxt){
dfs1(e[i].v,u,depth+1);
siz[u]+=siz[e[i].v];
if(siz[son[u]]<siz[e[i].v]){
son[u]=e[i].v;
}
}
}
void dfs2(ll u,ll high){
dfn[u]=++cnt,rk[cnt]=u,top[u]=high;
if(!son[u]) return ;
dfs2(son[u],high);
for(re i=head[u];i;i=e[i].nxt){
if(e[i].v==son[u]) continue;
dfs2(e[i].v,e[i].v);
}
}
inline ll find(ll x){
while(1){
ll dad=*--s.upper_bound(dfn[x]);
if(dad>=dfn[top[x]]) return rk[dad];
x=fa[top[x]];
}
}
inline ll ask(ll x){ return A.query2(dfn[x])-A.query2(dfn[x]-1)+B.query(rt[find(x)],1,n,dfn[x],dfn[x]); }
signed main(){
n=read(),ops=read(); ll u,v,w,opt,res;
for(re i=2;i<=n;i++) v=read(),add(v,i);
dfs1(1,0,0),dfs2(1,1); s.insert(1),B.build(rt[1],1,n);
while(ops--){
opt=read(),u=read(),now=u;
if(opt==1) printf("%u\n",ask(u));
else if(opt==2) w=read(),B.update(rt[u],1,n,1,n,w);
else if(opt==3){
v=find(u),now=v,res=A.query1(dfn[u]+siz[u]-1)-A.query1(dfn[u]-1);
if(u!=v) res+=B.query(rt[v],1,n,dfn[u],dfn[u]+siz[u]-1);
printf("%u\n",res);
}
else if(opt==4){
w=read(); A.update2(dfn[u],w),A.update2(dfn[u]+siz[u],-w);
v=find(u),now=v;
if(u!=v) B.update(rt[v],1,n,dfn[u],dfn[u]+siz[u]-1,-w);
}
else if(opt==5){
s.insert(dfn[u]),v=find(fa[u]); B.split(rt[v],rt[u],1,n,dfn[u],dfn[u]+siz[u]-1);
w=B.tr[rt[u]].w; A.update1(dfn[u],w),A.update1(dfn[v],-w);
}
else if(opt==6){
s.erase(dfn[u]); w=B.tr[rt[u]].w;
v=find(fa[u]); B.merge(rt[v],rt[u],1,n);
A.update1(dfn[u],-w),A.update1(dfn[v],w);
}
}
exit(0);
}

浙公网安备 33010602011771号