• 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
    
    */


  • 相关阅读:
    ubuntu 升级到5.1kernel,打开bbr
    python json.loads json.dumps的区别
    centos7 install vim8
    Linux的Network Tunnel技术
    Linux内核网络数据包处理流程
    CAD2010 破解方法
    [原创]MSP430FR4133练习(一):GPIO输入电平状态判断
    [原创] Xinput_1.3.DLL / MSVCR100.DLL文件缺失解决办法
    [原创]找不到mswinsck.ocx的解决办法
    Windows7系统推荐
  • 原文地址:https://www.cnblogs.com/llguanli/p/6848108.html
Copyright © 2020-2023  润新知