zoukankan      html  css  js  c++  java
  • [拒绝毒瘤的小清新系列] give you a tree

    题面在这里!

    (小声)这其实是我读错某题之后自己出的一道题。。。。。。

        正解也很简单啦,直接扫描线+线段树水过(考虑一个合法的区间正好有 siz-1 对树上相邻的点对)23333

    #include<cstdio>
    #include<vector>
    #define ll long long
    using namespace std;
    const int N=300005;
    #define pb push_back
    #define lc (o<<1)
    #define mid (l+r>>1)
    #define rc ((o<<1)|1)
    
    vector<int> g[N];
    int mx[N*4],sum[N*4],tag[N*4],le,ri,w,n;
    ll ans=0;
    
    inline void maintain(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 pushdown(int o){
    	if(tag[o]){
    		work(lc,tag[o]),work(rc,tag[o]);
    		tag[o]=0;
    	}
    }
    
    void ud1(int o,int l,int r){
    	if(l>=le&&r<=ri){ work(o,w); return;}
    	
    	pushdown(o);
    	
    	if(le<=mid) ud1(lc,l,mid);
    	if(ri>mid) ud1(rc,mid+1,r);
    	
    	maintain(o);
    }
    
    void ud2(int o,int l,int r){
    	if(l==r){ sum[o]=1,mx[o]=l; return;}
    	
    	pushdown(o);
    	
    	if(le<=mid) ud2(lc,l,mid);
    	else ud2(rc,mid+1,r);
    	
    	maintain(o);
    }
    
    inline void solve(){
    	for(int i=1;i<=n;i++){
    		le=i,ud2(1,1,n),le=w=1;
    		
    		for(int j:g[i]) ri=j,ud1(1,1,n); 
    		
    		ans+=(ll)sum[1];
    	}
    }
    
    int main(){
    	scanf("%d",&n);
    	int uu,vv;
    	for(int i=1;i<n;i++){
    		scanf("%d%d",&uu,&vv);
    		if(uu>vv) swap(uu,vv);
    		g[vv].pb(uu);
    	}
    	
    	solve();
    	
    	printf("%lld
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    sizeof()使用错例:sizeof(i++)
    修改linux命令符和解决命令符太长的问题
    【转载】阻止拷贝的三种方式
    git命令几个总结
    scp用法
    RAII
    a linked list
    c++11之函数式编程实例
    [转]基于SAML的单点登录介绍
    [转]OAuth、OAuth2与OpenID区别和联系
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9243970.html
Copyright © 2011-2022 走看看