zoukankan      html  css  js  c++  java
  • HDU 3564 Another LIS splay(水

    题意:

    给定一个空序列

    插入n个数(依次插入 1、2、3、4··n)

    以下n个数表示i插在哪个位置。

    每插入一个数后输出这个序列的lis

    然后。。。

    由于每次插入的数都是当前序列最大的数

    所以不会影响后面的数的dp值

    那么这个位置的dp值就是插入位置的前面最大dp值+1

    然后输出这个序列最大的dp值。

    ==

    思路:

    splay。

    。。

    Q:为何这题须要用splay,不是简单的线段树吗

    A: 由于我智商不够想不出线段树怎么写。。


    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #include <map>
    #include <cmath>
    template <class T>
    inline bool rd(T &ret) {
    	char c; int sgn;
    	if(c=getchar(),c==EOF) return 0;
    	while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    	sgn=(c=='-')?-1:1;
    	ret=(c=='-')?0:(c-'0');
    	while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    	ret*=sgn;
    	return 1;
    }
    template <class T>
    inline void pt(T x) {
        if (x <0) {
            putchar('-');
            x = -x;
        }
        if(x>9) pt(x/10);
        putchar(x%10+'0');
    }
    using namespace std;
    inline int Mid(int a,int b){return (a+b)>>1;}
    #define N 100010
    #define L(x) tree[x].ch[0]
    #define R(x) tree[x].ch[1]
    #define Siz(x) tree[x].siz
    #define Father(x) tree[x].fa
    #define Max(x) tree[x].max
    #define Val(x) tree[x].val
    #define Pt(x) tree[x].pt()
    struct node{
        int ch[2], siz, fa;
        int max, val;
        void pt(){printf("val:%d max:%d siz:%d fa:%d{%d,%d}
    ", val,max,siz,fa,ch[0],ch[1]);}
    }tree[N*2];
    int tot, root;
    void Newnode(int &id, int val, int fa, int siz = 1){
        id = ++tot;
        L(id) = R(id) = 0;
        Father(id) = fa;
        Siz(id) = siz;
        Max(id) = Val(id) = val;
    }
    
    void push_up(int id){
        Siz(id) = Siz(L(id)) + Siz(R(id)) +1;
        Max(id) = max(Max(R(id)), Max(L(id)));
        Max(id) = max(Val(id), Max(id));
    }
    void push_down(int id){}
    
    void Rotate(int id, int kind){
        int y = Father(id);
        push_down(y); push_down(id); //here
        tree[y].ch[kind^1] = tree[id].ch[kind];
        Father(tree[id].ch[kind]) = y;
        if(Father(y))
            tree[Father(y)].ch[R(Father(y))==y] = id;
        Father(id) = Father(y);
        Father(y) = id;
        tree[id].ch[kind] = y;
        push_up(y);
    }
    void splay(int id, int goal){
        push_down(id);
        while(Father(id) != goal){
            int y = Father(id);
            if(Father(y) == goal)
                Rotate(id, L(y)==id);
            else
            {
                int kind = L(Father(y)) == y;
                if(tree[y].ch[kind] == id)
                {
                    Rotate(id, kind^1);
                    Rotate(id, kind);
                }
                else
                {
                    Rotate(y, kind);
                    Rotate(id,kind);
                }
            }
        }
        push_up(id);
        if(goal == 0)root = id;
    }
    int Get_kth(int kth, int sor){//找到在sor后面的第k个数
        push_down(sor);
        int id = sor;
        while(Siz(L(id)) != kth){
            if(Siz(L(id)) > kth)
                id = L(id);
            else
            {
                kth -= (Siz(L(id))+1);
                id = R(id);
            }
            push_down(id);
        }
        return id;
    }
    void init(){
    	Father(0) = L(0) = R(0) = Siz(0) = 0;
    	Max(0) = 0;
    	tot = 0;
    	Newnode(root, 0, 0);
    	Newnode(R(root), 0, root);
    	push_up(root);
    }
    void debug(int x){
    	printf("%d:
    ", x);
    	Pt(x);
    	if(L(x))
    		debug(L(x));
    	if(R(x))
    		debug(R(x));
    }
    void insert(int pos){
    	splay(1, 0);
    	int u = Get_kth(pos, 1);
    //	if(pos == 2){cout<<"=="; debug(root);}
    	int v = Get_kth(pos+1, 1);
    	splay(u, 0);
    	splay(v, root);
    //	if(pos == 2){cout<<"=="; debug(root);}
    	Newnode(L(v), max(Val(root), Max(L(root))) +1, v);
    	push_up(v);
    	push_up(u);
    //	printf("[%d,%d]
    ", u, v);
    }
    
    int n;
    int main() {
    	int T, Cas = 1; cin>>T;
        while(T--){
        	rd(n);
        	init();
        //	debug(root);
        	printf("Case #%d:
    ", Cas++);
        	for(int i = 1, m; i <= n; i++){
        		rd(m);
        		insert(m);
        	//	printf("id:%d, pos:%d
    ", i, m);    		debug(root);
        		pt(Max(root)); putchar('
    ');
        		splay(tot, 0);
        	//	puts("================");debug(root);
        	}/**/
            puts("");
        }
        return 0;
    }
    /*
    1
    7
    0 1 1 1 0 4 1
    
    */


  • 相关阅读:
    xls与csv文件的区别
    青音,经典爱情语录
    win7用户账户自动登录方法汇总
    How to using Procedure found Lead Blocker
    FTS(3) BSD 库函数手册 遍历文件夹(二)
    FTS(3) BSD 库函数手册 遍历文件夹(一)
    DisplayMetrics类 获取手机显示屏的基本信息 包括尺寸、密度、字体缩放等信息
    About App Distribution 关于应用发布
    FTS(3) 遍历文件夹实例
    OpenCV 2.1.0 with Visual Studio 2008
  • 原文地址:https://www.cnblogs.com/llguanli/p/6848108.html
Copyright © 2011-2022 走看看