• 【LOJ2831】「JOISC 2018 Day 1」道路建设(LCT+树状数组)


    点此看题面

    • (n)个点,每个点有一个初始权值。
    • 共执行(n-1)次操作,每次会选择一个与(1)号点连通的点(x)和一个与(1)号点不连通的点(y),在它们之间连一条边。操作的代价是从(1)(x)路径上所有点权的逆序对个数,且连边后(1)(x)所有点的点权都将变成(y)的点权。
    • 给出每次的(x,y),求每次操作的代价。
    • (nle10^5)

    (LCT)(Access)操作

    每次要求出(1)(x)的路径并整体赋值,发现这就相当于(LCT)(Access)操作,满足(LCT)中每棵(Splay)维护的所有点权值相同。

    因此我们只要在(Splay)上维护一个子树大小以及子树赋值标记,询问时暴力往上(Access)一波,用一个树状数组求逆序对即可。

    一开始离散化写错还调了挺久。。。

    代码:(O(nlog^2n))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    using namespace std;
    int n,a[N+5],dc,dv[N+5];
    namespace FastIO
    {
    	#define FS 100000
    	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
    	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
    	int OT;char oc,FI[FS],FO[FS],OS[30],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
    	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
    	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
    	Tp I void writeln(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc('
    ');}
    }using namespace FastIO;
    struct TreeArray
    {
    	int a[N+5];I void U(RI x,CI v) {W(x<=dc) a[x]+=v,x+=x&-x;}//单点修改
    	I int Q(RI x,RI t=0) {W(x) t+=a[x],x-=x&-x;return t;}//前缀求和
    }A;
    class LinkCutTree
    {
    	private:
    		#define PU(x) (O[x].Sz=O[O[x].S[0]].Sz+O[O[x].S[1]].Sz+1)
    		#define IR(x) (O[O[x].F].S[0]^x&&O[O[x].F].S[1]^x)
    		#define Wh(x) (O[O[x].F].S[1]==x)
    		#define Co(x,y,d) (O[O[x].F=y].S[d]=x)
    		#define PD(x) (O[x].G&&(AS(O[x].S[0],O[x].G),AS(O[x].S[1],O[x].G),O[x].G=0))
    		#define AS(x,v) (O[x].V=O[x].G=v)
    		int St[N+5],Pt[N+5],Gt[N+5];struct node {int Sz,V,G,F,S[2];}O[N+5];
    		I void Ro(RI x) {RI f=O[x].F,p=O[f].F,d=Wh(x);
    			!IR(f)&&(O[p].S[Wh(f)]=x),O[x].F=p,Co(O[x].S[d^1],f,d),Co(f,x,d^1),PU(f);}
    		I void S(RI x) {RI f=x,T=0;W(St[++T]=f,!IR(f)) f=O[f].F;
    			W(T) PD(St[T]),--T;W(!IR(x)) f=O[x].F,!IR(f)&&(Ro(Wh(f)^Wh(x)?x:f),0),Ro(x);PU(x);}
    		I void Ac(RI x)
    		{
    			RI i,o,y,T=0;long long t=0;for(y=0;x;O[x].S[1]=y,PU(x),x=O[y=x].F)
    				S(x),O[x].S[1]=0,PU(x),t+=1LL*O[x].Sz*A.Q(O[x].V-1),A.U(O[x].V,O[x].Sz),Pt[++T]=O[x].V,Gt[T]=O[x].Sz;
    				//删去原先的右儿子(注意暂不更新新的右儿子);答案加上当前sz乘上小于当前权值的点数;树状数组上修改
    			writeln(t);W(T) A.U(Pt[T],-Gt[T]),--T;//清空树状数组
    		}
    	public:
    		I void Init() {for(RI i=1;i<=n;++i) O[i].Sz=1,O[i].V=a[i];}
    		I void Link(CI x,CI y) {Ac(x),S(x),O[y].F=x,AS(x,O[y].V);}//连边,然后赋值
    }LCT;
    int main()
    {
    	RI i;for(read(n),i=1;i<=n;++i) read(a[i]),dv[i]=a[i];sort(dv+1,dv+n+1),dc=unique(dv+1,dv+n+1)-dv-1;
    	for(i=1;i<=n;++i) a[i]=lower_bound(dv+1,dv+dc+1,a[i])-dv;LCT.Init();//离散化
    	RI x,y;for(i=1;i^n;++i) read(x),read(y),LCT.Link(x,y);return clear(),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    Image Segmentation Using Text and Image Prompts论文阅读笔记
    CRIS: CLIPDriven Referring Image Segmentation论文阅读笔记
    SSUL: Semantic Segmentation with Unknown Label for Exemplarbased ClassIncremental Learning 论文阅读笔记
    Compacting, Picking and Growing for Unforgetting Continual Learning论文阅读笔记
    Codeforces Round #825 (Div. 2) D. Equal Binary Subsequences
    Overleaf编译LaTex报错:Missing number, treated as zero.<to be read again>
    DenseCLIP LanguageGuided Dense Prediction with ContextAware Prompting论文阅读笔记
    macOS CPU环境安装mmsegmentation踩坑记录
    Linux安装git
    Docker容器迁移
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/LOJ2831.html
Copyright © 2020-2023  润新知