1. 程式人生 > >【BZOJ】【P2212&P3702】【Poi2011】【Tree Rotations】【二叉樹】【題解】【啟發式合併】

【BZOJ】【P2212&P3702】【Poi2011】【Tree Rotations】【二叉樹】【題解】【啟發式合併】

啟發式合併不解釋

Code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+5;
struct node{  
    int val,key,size,s;  
    node *c[2];  
    node(int _val=0,node *C=0){  
        val=_val;key=rand();  
        size=s=1;c[0]=c[1]=C;  
    }void rz(){  
        size=c[0]->size+s+c[1]->size;  
    }  
};
struct Treap{  
    node *root,*Null;  
    Treap(){  
        Null=new node(0,0);  
        Null->size=Null->s=0;Null->key=INT_MAX;  
        Null->c[0]=Null->c[1]=Null;root=Null;  
    }  
    void rot(node *&t,bool d){  
        node *p=t->c[d];t->c[d]=p->c[!d];  
        p->c[!d]=t;t->rz();p->rz();t=p;  
    }  
    void _insert(node *&t,int x){  
        if(t==Null){t=new node(x,Null);return;}  
        if(t->val==x){t->s++;t->size++;return;}  
        _insert(t->c[x>t->val],x);  
        if(t->c[x>t->val]->key<t->key)  
        rot(t,x>t->val);else t->rz();  
    }  
    int _kth(node *t,int x){  
        int r=t->c[0]->size;  
        if(x<=r)return _kth(t->c[0],x);  
        else if(x>r+t->s) return _kth(t->c[1],x-r-t->s);  
        return t->val;  
    }  
    int _rank(node *t,int x){  
    	if(t==Null)return 0;
        int r=t->c[0]->size;  
        if(x<t->val)return _rank(t->c[0],x);  
        else if(x>t->val)return _rank(t->c[1],x)+r+t->s;  
        return r;  
    }  
    void erase(node *t){
    	if(t->c[0]!=Null)erase(t->c[0]);
    	if(t->c[1]!=Null)erase(t->c[1]);
    	delete t;
    }
    void clear(){erase(root);}
    void insert(int x){_insert(root,x);}  
    int kth(int x){return _kth(root,x);}  
    int rank(int x){return _rank(root,x);}    
    int size(){return root->size;}
}T[maxn];  
typedef long long LL;
int n;
LL cnt[maxn],ans;
int tot=1;
int getint(){
	int res=0;char c=getchar();
	while(!isdigit(c))c=getchar();
	while(isdigit(c))res=res*10+c-'0',c=getchar();
	return res;
}
void dfs(int u){
	int x=getint();
	if(!x){
		int l=++tot,r=++tot;
		dfs(l);
		dfs(r);
		if(T[l].size()<T[r].size())swap(l,r);
		LL res=0;
		for(int i=1;i<=T[r].size();i++)
			res+=T[l].rank(T[r].kth(i));
		ans+=min(res,(LL)T[l].size()*T[r].size()-res);
		for(int i=1;i<=T[r].size();i++){
			int k=T[r].kth(i);
			T[l].insert(k);
		}T[u]=T[l];
	}else T[u].insert(x);	
}
int main(){
	scanf("%d",&n);
	dfs(1);
	cout<<ans<<endl;
	return 0;
}


相關推薦

的結構體表示摘抄自嚴長生老師的網站

採用鏈式儲存 typedef struct BiTNode{ TElemType data;//資料域 struct BiTNode *lchild,*rchild;//左右孩子指標 }BiTNode,*BiTree; 若需訪問父節點,可如下表示 typedef str

的確定 :三種遍歷

已知二叉樹的後序和中序來確定二叉樹 題目【L2-006 樹的遍歷】 #include<bits/stdc++.h> using namespace std; const int N

Java面試12常用演算法(冒泡、插入、選擇、快速)和詳解

常用演算法(冒泡、插入、選擇、快速)和二叉樹詳解     同一問題可用不同演算法解決,而一個演算法的質量優劣將影響到演算法乃至程式的效率。演算法分析的目的在於選擇合適演算法和改進演算法。   電腦科學中,演算法的時間複雜度是一個函式,它定量描述了該演算法的執行時間。這是一個關於

劍指offer第二十四題中和為某一值的路徑c++實現

題目描述 輸入一顆二叉樹和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。 先序遍歷二叉樹,用一個數組記錄當前路徑,如果遍歷到葉子節點就進行判斷是否和給定值相等。 class Solution { public: vect

如何寫一顆(遞迴)菜鳥學習日記

老規矩,開篇點題,今天寫了二叉樹,整理總結一下 要寫二叉樹,先畫出一顆來 二叉樹我是用連結串列來實現的 1、每一個節點包含資料,左指標和右指標,分別指向左孩子和右孩子 //建立節點型別 //節點中有資料,有指標 template<

LeetCode-面試演算法經典-Java實現145-Binary Tree Postorder Traversal(非遞迴後序遍歷)

原題   Given a binary tree, return the postorder traversal of its nodes’ values.   For exampl

leetcode145Binary Tree Postorder Traversal(非遞迴後序遍歷)

二叉樹後序遍歷非遞迴方法很多書和部落格已經講的很清楚啦,這裡就是記錄一下方便自己日後看 基本思路是: 利用棧來實現 先找到最左節點,過程中的節點都入棧 如果該節點沒有右孩子或前一步訪問了右孩子(根據後序遍歷二叉樹的特點可以知道,如果當前節點有右孩子,則訪問當前節點前一定是

的遍歷 &NOIP2001普及組& 洛谷 P1030 求先序排列

題目 輸出 image pre ext bubuko 二叉樹 找到 pan 題目鏈接 https://www.luogu.org/problemnew/show/P1030 模板題 先講一下二叉樹的遍歷 二叉樹的遍歷 分類 性質 求法 分為三類:

BZOJP2212&P3702Poi2011Tree Rotations題解啟發式合併

啟發式合併不解釋 Code: #include<bits/stdc++.h> using namespace std; const int maxn=4e5+5; struct node{ int val,key,size,s; nod

算法模板

treenode tor bsp res stack ack 算法 == oid 模板: 1.先序遍歷三種方法 1)叠代: class Solution { public: /** * @param root: The root of binary tr

數據結構(c++)

public ear ren fontsize tree fault left reorder 個數 頭文件: #include <iostream> using namespace std; template<class Type> cl

3、非線性結構--——數據結構基礎篇

位置 enter 深度 基礎 表達式 左右 -a 基礎篇 先序遍歷 非線性結構--樹與二叉樹 二叉樹的基礎知識:         二叉樹的特點:             1、每個結點的度<=2             2、二叉樹是有序樹         二叉樹的五種不

劍指offer之從上往下打印

emp pub push coder 二叉 spa cti public ott 題目:   從上往下打印二叉樹 鏈接:   https://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701?tpId=13

數據結構與算法遞歸與非遞歸遍歷(附完整源碼)(轉)

style stack gravity text 一個 eat 遞歸遍歷 deb 雙向 轉自:http://blog.csdn.net/ns_code/article/details/12977901 二叉樹是一種非常重要的數據結構,很多其他數據機構都是基於二叉樹的基礎

luogu1040加分

num sign 中序 計算方法 個數 整數 一個 -m 輸入輸出 題目描述 設一個n個節點的二叉樹tree的中序遍歷為(1,2,3,…,n),其中數字1,2,3,…,n為節點編號。每個節點都有一個分數(均為正整數),記第i個節點的分數為di,tree及它的每個子樹都有一個

LeetCode-面試算法經典-Java實現107-Binary Tree Level Order Traversal II(層序遍歷II)

lin -m length ret itl pub util 實現類 markdown 【107-Binary Tree Level Order Traversal II(二叉樹層序遍歷II)】 【LeetCode-面試算法經典-Java實現】【全

1064. Complete Binary Search Tree (30)——PAT (Advanced Level) Practise

function namespace his () 技術 androi sed tel evel 題目信息 1064. Complete Binary Search Tree (30) 時間限制100 ms 內存限制65536 kB 代碼長度限制

LeetCode-面試算法經典-Java實現106-Construct Binary Tree from Inorder and Postorder Traversal(構造II)

struct ons node dcl 實現 ftl rsa tor var 【106-Construct Binary Tree from Inorder and Postorder Traversal(通過中序和後序遍歷構造二叉樹)】 【Lee

基礎練習區間DPcodevs1090 加分題解

border style script 全部 靈魂 noip 初始 mar 出現 2003 NOIP TG 題目描寫敘述 Description 設一個n個節點的二叉樹tree的中序遍歷為(l,2,3,…,n),當中數字1,2,3,…,n為節點編

2

填充 通過 nbsp 速度 消元 理解 .com 我們 rdquo 二叉樹簡介 ---------------------------註:本文所用的術語定義均來自國外大學和計算機文獻使用的定義,非國內教材。------------------------------ 二