zoukankan      html  css  js  c++  java
  • Luogu P3521 [POI2011]ROT-Tree Rotations

    题目链接 (Click) (Here)

    线段树合并,没想到学起来意外的很简单,一般合并权值线段树。

    建树方法和主席树一致,即动态开点。合并方法类似于(FHQ)的合并,就是把两棵树的信息整合到一个里面。暂时没写过定义域不同的线段树合并,具体方法也想象不出来,写到了再详细讲吧。

    算法复杂度:均摊(O(NlogN)),实际空间时间复杂度都不够稳定,需要谨慎使用。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 200010;
    #define ll long long
    #define mid ((l + r) >> 1)
    
    int n, pos;
    ll ANS = 0, ans1 = 0, ans2 = 0;
    
    struct node{
        int sumn, ls, rs;
    }t[N << 5];
    
    int cnt = 0; // 
    
    void update (int &nown, int l, int r) { 
        if (nown == 0) nown = ++cnt;
        t[nown].sumn++;
        if (l != r) {
        	if (pos <= mid) {
    	        update (t[nown].ls, l, mid);
    	    } else {
    	        update (t[nown].rs, mid + 1, r);
    		}
    	}
    }	
    
    void merge (int &lx, int rx) {
        if (lx * rx == 0) {
    		lx = lx + rx; 
    		return;
    	}
        t[lx].sumn += t[rx].sumn;
        ans1 += 1LL * t[t[lx].rs].sumn * t[t[rx].ls].sumn;
        ans2 += 1LL * t[t[lx].ls].sumn * t[t[rx].rs].sumn;
        merge (t[lx].ls, t[rx].ls);
        merge (t[lx].rs, t[rx].rs);
    }
    
    void solve (int &x) {
        int t, ls, rs; x = 0;
        cin >> t;
        if(t == 0) { 
            solve (ls); 
    		solve (rs);
            ans1 = ans2 = 0;
    		merge (x = ls, rs);
            ANS += min (ans1, ans2);
        } else {
            pos = t;
    		update (x, 1, n);
    	}
    }
    
    int main () {
        cin >> n;
    	int t = 0;
        solve (t);
        cout << ANS << endl;
    	return 0;
    }
    
  • 相关阅读:
    c语言中的隐式函数声明(转)
    static关键字
    Eclipse中spring项目的XML文件的问题
    spring 中c3p0的优化配置
    Mysql通过SQL脚本复制表
    tomcat 设置内存
    删除无限循环的文件夹-删除递归文件夹
    使用cnpm代替npm
    数据库框架的log4j日志配置
    Win7删除远程连接历史记录
  • 原文地址:https://www.cnblogs.com/maomao9173/p/10554898.html
Copyright © 2011-2022 走看看