zoukankan      html  css  js  c++  java
  • [Lydsy1806月赛] 路径统计

    题面在这里!

    xjb想的做法竟然不小心把std艹爆了qwq,我也很无奈啊....

        那接下来就说一下我的神奇做法qwq

        如果是经常读我博客的童鞋会发现其实我以前就想要做这个题啦,只不过当时读错题啦。。。以为[L,R]在树上只要形成联通块就可以了,于是就自己出了一个题

       

        那个题的做法是直接扫描线,因为[L,R]合法当且仅当 R-L = sum[L] ,其中sum[L] 表示以L 为左端点,目前扫描线为右端点的区间中在树上相邻的点对数,而扫描线右端点右移一位造成的影响只会是一些前缀的sum[]区间加,用线段树动态维护一下就好啦。(维护 区间加,最大值和其数量)

        于是那个题就这么做完了。。。。

        但是这个题还得要求 在树上形成的联通块是一个链。。。。。

        不过仔细想想,链无非就比联通块多一个限制:所有点的度数<=2

        所以我们就可以对于每个扫描线右端点R,去动态维护一个L,使得区间 [L,R] 在树上是若干链(当然也可以是一条啦),但是 [L-1,R]的点构成的子图中就有至少一个点的度数>2了。

        不难想到 L 关于 R 是具有单调性的,R增大L不会变小,并且 [L,R] 满足没有 >2的度数的点的话,[L+1,R]也满足;反之,[L,R]不满足的话那么 [L-1,R] 也不满足。。。。

        所以就可以用度数的关系轻松的O(N)维护这个玩意,复杂度还是在扫描线线段树那里。

        于是这个题也这么做完了23333

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    #define pb push_back
    #define lc (o<<1)
    #define mid (l+r>>1)
    #define rc ((o<<1)|1)
    const int N=250005;
    
    inline int read(){
    	int x=0; char ch=getchar();
    	for(;!isdigit(ch);ch=getchar());
    	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    	return x;
    }
    
    vector<int> g[N],h[N];
    int mx[N*4],tag[N*4],n,m,le,ri;
    int dg[N],num,L,sum[N*4],M,cnt,R;
    ll ans=0;
    
    inline void mt(int o){
    	mx[o]=max(mx[lc],mx[rc]);
    	sum[o]=(mx[lc]==mx[o]?sum[lc]:0)+(mx[rc]==mx[o]?sum[rc]:0);
    }
    
    inline void work(int o,int der){ tag[o]+=der,mx[o]+=der;}
    
    inline void pd(int o){
    	if(tag[o]){
    		work(lc,tag[o]),work(rc,tag[o]);
    		tag[o]=0;
    	}
    }
    
    void build(int o,int l,int r){
    	sum[o]=1,mx[o]=r;
    	if(l==r) return;
    	build(lc,l,mid),build(rc,mid+1,r);
    }
    
    void update(int o,int l,int r){
    	if(l>=le&&r<=ri){ work(o,1); return;}
    	pd(o);
    	if(le<=mid) update(lc,l,mid);
    	if(ri>mid) update(rc,mid+1,r);
    	mt(o);
    }
    
    void query(int o,int l,int r){
    	if(l>=le&&r<=ri){
    		if(mx[o]>M) M=mx[o],cnt=sum[o];
    		else if(mx[o]==M) cnt+=sum[o];
    		return;
    	}
    
    	pd(o);
    
    	if(le<=mid) query(lc,l,mid);
    	if(ri>mid) query(rc,mid+1,r);
    }
    
    inline void ADD(int x){
    	le=1;
    	for(int j=g[x].size()-1,i;j>=0;j--){
    		i=g[x][j],ri=i,update(1,1,n);
    		if(i>=L) num+=((++dg[x])==3)+((++dg[i])==3);
    	}
    }
    
    inline void Del(int x){
    	for(int j=h[x].size()-1,i;j>=0;j--){
    		i=h[x][j];
    		if(i<=R) num-=((--dg[x])==2)+((--dg[i])==2);
    	}
    }
    
    inline void solve(){
    	build(1,1,n),L=1;
    
    	for(int i=1;i<=n;i++){
    		ADD(i),R=i;
    		for(;num;L++) Del(L);
    
    		le=L,ri=i,M=0,query(1,1,n);
    		if(M==i) ans+=(ll)cnt;
    	}
    }
    
    int main(){
    	n=read();
    	for(int i=1,uu,vv;i<n;i++){
    		uu=read(),vv=read();
    		if(uu<vv) g[vv].pb(uu),h[uu].pb(vv);
    		else g[uu].pb(vv),h[vv].pb(uu);
    	}
    	solve(),printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    暑假训练第三周总结
    UVA 1212 Duopoly
    UVA 12125 March of the Penguins
    UVA 1345 Jamie's Contact Groups
    UVA 10806 Dijkstra, Dijkstra.
    暑假训练第一周总结
    HDU 5792 World is Exploding
    HDU 5791 Two
    HDU 5787 K-wolf Number
    Sql With as 用法
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9303423.html
Copyright © 2011-2022 走看看