zoukankan      html  css  js  c++  java
  • 雅礼集训2019 D7T2 Subsequence

    雅礼集训2019 D7T2 Subsequence

    image

    image


    直接贴题解:

    image

    平衡树代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define N 100005
    
    using namespace std;
    inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
    
    int n;
    ll a[N];
    int ch[N][2],fa[N];
    int size[N];
    ll p[N];
    #define ls ch[v][0]
    #define rs ch[v][1]
    int rt;
    void update(int v) {size[v]=size[ls]+size[rs]+1;}
    ll add[N];
    
    void Add(int v,ll f) {
    	p[v]+=f;
    	add[v]+=f;
    }
    
    void down(int v) {
    	if(add[v]) {
    		if(ls) Add(ls,add[v]);
    		if(rs) Add(rs,add[v]);
    		add[v]=0;
    	}
    }
    
    void rot(int v) {
    	int f=fa[v],gr=fa[f];
    	int sn=v==ch[f][1],son=ch[v][!sn];
    	if(gr) ch[gr][f==ch[gr][1]]=v;
    	ch[f][sn]=son;
    	ch[v][!sn]=f;
    	fa[v]=gr,fa[f]=v;
    	if(son) fa[son]=f;
    	update(f),update(v);
    }
    
    void splay(int v) {
    	static int st[N],top;
    	st[top=1]=v;
    	for(int i=v;fa[i];i=fa[i]) st[++top]=fa[i];
    	for(int i=top;i>=1;i--) down(st[i]);
    	while(fa[v]) {
    		int f=fa[v],gr=fa[f];
    		if(gr) rot(f==ch[gr][1]^v==ch[f][1]?v:f);
    		rot(v);
    	}
    	rt=v;
    }
    
    int tot;
    int Find(int k) {
    	int v=rt;
    	while(1) {
    		if(size[ls]+1==k) return v;
    		if(size[ls]>=k) v=ls;
    		else k-=size[ls]+1,v=rs;
    	}
    }
    
    int Find_rk(int v) {
    	splay(v);
    	return size[ls]+1;
    }
    
    void Insert(int &v,int k,int id) {
    	if(!v) {
    		v=id;
    		update(v);
    		return ;
    	}
    	if(size[ls]>=k-1) {
    		Insert(ls,k,id);
    		fa[ls]=v;
    	} else {
    		Insert(rs,k-size[ls]-1,id);
    		fa[rs]=v;
    	}
    	update(v);
    }
    
    int pos;
    void binary(int v,ll a,int pre,int &pos) {
    	if(!v) return ;
    	down(v);
    	ll now=pre+size[ls]+1;
    	if(a*now>=p[v]) {
    		pos=v;
    		binary(ls,a,pre,pos);
    	} else binary(rs,a,pre+size[ls]+1,pos);
    }
    
    void out(int v,ll &ans) {
    	if(!v) return ;
    	down(v);
    	out(ls,ans);
    	ans+=p[v];
    	cout<<ans<<" ";
    	out(rs,ans);
    }
    
    int main() {
    	n=Get();
    	for(int i=1;i<=n;i++) a[i]=Get();
    	rt=1;
    	update(rt);
    	p[rt]=a[1];
    	
    	for(int i=2;i<=n;i++) {
    		binary(rt,a[i],0,pos=i);
    		if(pos!=i) splay(pos);
    		int rk=pos==i?i:Find_rk(pos);
    		p[i]=a[i]*rk;
    		Insert(rt,rk,i);
    		splay(i);
    		if(ch[i][1]) Add(ch[i][1],a[i]);
    	}
    	ll ans=0;
    	out(rt,ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Xshell远程连接工具
    Linux系列之常用命令整理笔录
    板卡
    禅道Bug等级划分标准
    CPU与GPU的区别
    PICT用例组合工具简介与使用教程
    alpha测试和beta测试的区别
    性能基础知识学习之八---loadrunner中run-time setting常用功能
    性能基础知识学习之七---loadrunner压测
    性能基础知识学习之六---socket接口测试
  • 原文地址:https://www.cnblogs.com/hchhch233/p/11085339.html
Copyright © 2011-2022 走看看