只想到了朴素的n^2做法,然后发现可以用splay维护。于是调了几个小时的splay。。。

splay的元素是从第二个开始的!第一个是之前插入的头节点!

 #include <cstdio>
#include <algorithm>
#include <cstring> using namespace std; #define Key_value ch[ch[root][1] ][0] const int maxn = 5e5+;
const int INF = 0x3f3f3f3f; int pre[maxn],ch[maxn][],key[maxn],sz[maxn];
int root,tot1;
int rev[maxn],ma[maxn],add[maxn];
int s[maxn],tot2;
int a[maxn];
//int n,q; void Treavel(int x)
{
if(x)
{
Treavel(ch[x][]);
printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d size= %2d ma=%2d add=%2d\n",x,ch[x][],ch[x][],pre[x],key[x],sz[x],ma[x],add[x]);
Treavel(ch[x][]);
}
}
void debug()
{
printf("root:%d\n",root);
Treavel(root);
}
// void NewNode(int &r,int father,int k)
{
if(tot2) r = s[tot2--];
else r = ++tot1;
pre[r] = father;
ch[r][] = ch[r][] = ;
key[r] = k;
ma[r] = k;
rev[r] = add[r] = ;
sz[r] = ;
} void Update_add(int r,int c)
{
if(!r) return ;
key[r] += c;
ma[r] += c;
add[r] += c;
} void Update_rev(int r)
{
if(!r) return ;
swap(ch[r][],ch[r][]);
rev[r] ^= ;
} void push_up(int r)
{
int lson = ch[r][],rson = ch[r][];
sz[r] = sz[lson] + sz[rson] + ;
//ma[r] = max(max(ma[lson],ma[rson]),key[r]);
ma[r] = max(max(ma[lson],ma[rson]),key[r]);
}
void update_same(int r,int c)
{
if(!r) return ;
int lson = ch[r][],rson = ch[r][];
key[r] = c;
//ma[r] = max(max(ma[lson],ma[rson]),c);
ma[r] = c;
}
void push_down(int r)
{
if(rev[r])
{
Update_rev(ch[r][]);
Update_rev(ch[r][]);
rev[r] = ;
}
if(add[r])
{
Update_add(ch[r][],add[r]);
Update_add(ch[r][],add[r]);
add[r] = ;
}
} void Build(int &x,int l,int r,int father)
{
if(l>r) return ;
int mid = (l+r)>>;
NewNode(x,father,a[mid]);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
push_up(x);
} void Init(int x)
{
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = sz[root] = pre[root] = ;
rev[root] = key[root] = ;
ma[root] = ;
NewNode(root,,-);
NewNode(ch[root][],root,-);
//for(int i=1;i<=n;i++) scanf("%d",&a[i]);
a[] = x;
//n = 1;
Build(Key_value,,,ch[root][]);
push_up(ch[root][]);
push_up(root);
} void Rotate(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind] ] = y;
if(pre[y])
ch[pre[y] ][ch[pre[y]][]==y ] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
void Splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r] ] == goal)
{
push_down(pre[r]);
push_down(r);
Rotate(r,ch[pre[r]][] == r);
}
else
{
push_down(pre[pre[r] ]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y] ][] == y;
if(ch[y][kind] == r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
push_up(r);
if(goal == ) root = r;
}
} int Get_kth(int r,int k)
{
push_down(r);
int t = sz[ch[r][] ] + ;
if(t == k) return r;
if(t > k) return Get_kth(ch[r][],k);
else return Get_kth(ch[r][],k-t);
} void Insert(int pos,int x)
{
//for(int i=0;i<tot;i++) scanf("%d",&a[i]);
int tot = ;
a[] = x;
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+) , root);
Build(Key_value,,tot-,ch[root][]);
push_up(ch[root][]);
push_up(root);
}
void erase(int r)
{
if(!r) return ;
s[++tot2] = r;
erase(ch[r][]);
erase(ch[r][]);
}
void Delete(int pos,int tot)
{
Splay(Get_kth(root,pos) ,);
Splay(Get_kth(root,pos+tot+) , root);
erase(Key_value);
pre[Key_value] = ;
Key_value = ;
push_up(ch[root][]);
push_up(root);
} void Reverse(int pos,int tot)
{
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+tot+), root);
Update_rev(Key_value);
} void Add(int pos,int tot,int c)
{
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+tot+) , root);
Update_add(Key_value,c);
push_up(ch[root][]);
push_up(root);
}
void Make_same(int pos,int tot,int c)
{
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+tot+) , root);
//printf("tihuan\n");
//debug();
update_same(Key_value,c);
push_up(ch[root][]);
push_up(root);
}
int Get_max(int pos,int tot)
{
Splay(Get_kth(root,pos) , );
Splay(Get_kth(root,pos+tot+) , root);
push_down(root);
push_down(ch[root][]);
return ma[Key_value];
}
int Get_final_ans(int pos,int tot,int x)
{
int low = pos+,high = pos+tot-;
int mid;
while(low <= high)
{
mid = (low+high)>>;
int b = key[Get_kth(root,mid)];
//printf("mid:%d k:%d\n",mid,b);
if(x >= b) low = mid+;
else high = mid -;
}
//printf("l:%d h:%d m:%d\n",low,high,mid);
return (low+high)>>;
} void Revolve(int l,int r,int t)
{
if(!t) return ;
int c = r - t;
Splay(Get_kth(root,l) , );
Splay(Get_kth(root,c+),root);
int tmp = Key_value;
Key_value = ;
push_up(ch[root][]);
push_up(root);
Splay(Get_kth(root,r-c+l) , );
Splay(Get_kth(root,r-c+l+) , root);
Key_value = tmp;
pre[Key_value] = ch[root][];
push_up(ch[root][]);
push_up(root);
} int save[maxn];
int T,N;
int LL,RR;
int DP(int l,int n)
{
if(n==) return ;
int i,len=,pos;
Init(save[l]);
//debug();
//printf("---\n");
for(int i=l+;i<=n;i++)
{
//printf("save:%d len:%d max:%d\n",save[i],len,Get_max(1,len));
if(save[i] == )
{
Add(,len,);
Insert(,);
len++;
}
else if(save[i] > Get_max(,len))
{
//printf("max:%d\n",Get_max(1,len));
Insert(len+,save[i]);
len++;
}
else{
pos = Get_final_ans(,len,save[i]);
//printf("pos:%d\n",pos);
//Add(pos,1,save[i]-key[Get_kth(root,pos)]);
Make_same(pos,,save[i]);
} //debug();
//printf("---\n");
}
return len;
}
bool flag = false;
void deal()
{
int i = ;
while( save[i]== && i <= N) i++;
LL = i;
i = N;
if(LL>=N ) {flag = true;return;}
while(save[i] == && i >= ) i--;
RR = i;
}
int main()
{
//freopen("input","r",stdin);
//freopen("splay.out","w",stdout);
scanf("%d",&T);
for(int cas=;cas<=T;cas++)
{
scanf("%d",&N);
for(int i=;i<=N;i++)
{
scanf("%d",&save[i]);
}
flag = false;
deal();
if(flag){
printf("Case #%d: %d\n",cas,N);
continue;
}
//printf("LL:%d RR:%d\n",LL,RR);
int ans = DP(LL,RR);
printf("Case #%d: %d\n",cas,ans+LL-+(N-RR));
}
}
/*
int m;
int main()
{
while(~scanf("%d ",&n))
{
Init();
//debug();
scanf("%d ",&m);
char op[10];
for(int i=0;i<m;i++)
{
scanf(" %s",op);
//printf("i:%d op:%s\n",i,op);
int x,y,c,t;
if(op[0] == 'A') //add
{
scanf("%d%d%d",&x,&y,&c);
Add(x,y-x+1,c);
}
else if(op[0] == 'I') //insert
{
scanf("%d",&x);
Insert(x,1);
}
else if(op[0] == 'D') //delete
{
scanf("%d",&x);
Delete(x,1);
}
else if(op[0] == 'M') //min
{
scanf("%d%d",&x,&y);
printf("%d\n",Get_min(x,y-x+1));
}
else if(op[0] == 'R' && op[3] == 'E')//reverse
{
scanf("%d%d",&x,&y);
Reverse(x,y-x+1);
}
else //revolve
{
scanf("%d%d%d",&x,&y,&t);
t = (t%(y-x+1)+(y-x+1))%(y-x+1);
Revolve(x,y,t);
}
//debug();
}
}
}
*/

HDU5773-The All-purpose Zero-多校#41010-最长上升子序列问题的更多相关文章

  1. 牛客多校第五场 G subsequence 1 最长公共子序列/组合数

    题意: 给定两个由数字组成的序列s,t,找出s所有数值大于t的子序列.注意不是字典序大. 题解: 首先特判s比t短或一样长的情况. 当s比t长时,直接用组合数计算s不以0开头的,长度大于t的所有子序列 ...

  2. Contest2071 - 湖南多校对抗赛(2015.03.28)

    Contest2071 - 湖南多校对抗赛(2015.03.28) 本次比赛试题由湖南大学ACM校队原创 http://acm.csu.edu.cn/OnlineJudge/contest.php?c ...

  3. 2014哈商大ICPC/ACM校赛解题报告

    被debug邀请去參加校赛,哎,被虐..我对不起工大.. 由于本人不搞ACM,算法处于HelloWorld水准.. 虽然题目除了鸟不拉屎星人之外都非常水,但我能做到这个程度,全然是超水平发挥了.. 数 ...

  4. 2017 多校4 Security Check

    2017 多校4 Security Check 题意: 有\(A_i\)和\(B_i\)两个长度为\(n\)的队列过安检,当\(|A_i-B_j|>K\)的时候, \(A_i和B_j\)是可以同 ...

  5. hdu6078[优化递推过程] 2017多校4

    这道题一眼看过去好像和最长公共子序列有点像. 一开始只想到暴力的推法, 令dp[i][j][k]表示 a[i]=b[j](即以ai,bj为结尾的波浪序列的方案数), 且最终状态为k(0,1分别代表下降 ...

  6. 蒟蒻ACMer回忆录 · 一段弱校ACM的奋斗史

    三年半的ACM生涯终于迎来了终点,退役之时,感慨万分,故写此文以纪念逝去的时光,那些为ACM拼搏的日子,那段弱校ACM的奋斗史. 三年半的ACM生涯,窝见证了CUMT从打铁到铜牌的突破,又见证了从铜牌 ...

  7. 2015 GDUT校赛

    周末打了个GDUT的校赛,也是作为SCAU的一场个人排位. 比赛中竟然卡了个特判,1个半钟就切了5条了,然后一直卡. 还有其他两条可以做的题也没法做了,性格太执着对ACM来说也是错呀. 讲回正题 . ...

  8. HDU4512完美队形I && HDU1423 Greatest Common Increasing Subsequence (LCIS)

    填坑的时候又到啦,校赛因为不会LCIS所以吃了大亏,这里要补起来.LCIS就是在两个串里找最长上升子序列,相关的博客有很多,这里自己就不写那么多了. http://www.cnblogs.com/ja ...

  9. Codeforces245H - Queries for Number of Palindromes(区间DP)

    题目大意 给定一个字符串s,q个查询,每次查询返回s[l-r]含有的回文子串个数(题目地址) 题解 和有一次多校的题目长得好相似,这个是回文子串个数,多校的是回文子序列个数 用dp[i][j]表示,s ...

随机推荐

  1. .NET Core Community 第二个千星项目诞生:Util

    本文所有打赏将全数捐赠于 NCC(NCC 的资金目前由 倾竹大人 负责管理),请注明捐赠于 NCC.捐赠情况将由倾竹大人另行公示. 项目简介 作为一款旨在提升小型团队开发输出能力.提高团队效率.降低项 ...

  2. golang中的context包

    标准库的context包 从设计角度上来讲, golang的context包提供了一种父routine对子routine的管理功能. 我的这种理解虽然和网上各种文章中讲的不太一样, 但我认为基本上还是 ...

  3. 从 0 到 1 实现 React 系列 —— 2.组件和 state|props

    看源码一个痛处是会陷进理不顺主干的困局中,本系列文章在实现一个 (x)react 的同时理顺 React 框架的主干内容(JSX/虚拟DOM/组件/生命周期/diff算法/setState/ref/. ...

  4. Paypal2017实习生-软件开发-B卷

    1. [编程|15分] Calculate survival fishes时间限制:1秒空间限制:32768K题目描述Given two zero-indexed arrays A and B con ...

  5. 实时采集新加坡交易所A50指数

    http://www.investing.com/indices/ftse-china-a50 前段时间有人问我如何得到这个网页的实时指数变化,经过抓包发现该网站提供的指数实时变化是通过Websock ...

  6. 正则表达式验证input文本框

    方便以后的查找,直接copy代码在这里了. eg: //公司邮箱验证 if ($("#Email").val() != "") { var myreg = /^ ...

  7. 【学习总结】Master课程 之 虚拟化与云计算

    Section 1- Cloud Computing Introduction-云计算介绍 1-What can Cloud Computing do? - 云计算可以做什么? 服务模式:美国国家标准 ...

  8. Python解释器有哪些?Python解释器种类

    Python是一门解释器语言,代码想运行,必须通过解释器执行,Python存在多种解释器,分别基于不同语言开发,每个解释器有不同的特点,但都能正常运行Python代码,以下是常用的五种Python解释 ...

  9. babel (三) babel polly-fill

    Babel includes a polyfill that includes a custom regenerator runtime and core-js. This will emulate ...

  10. flutter开发vscode用模拟器调试

    android studio的太重,我装的是android sdk,使用avd的模拟器启动黑屏 启动夜神模拟器(已卸载) 建立连接: adb connect 127.0.0.1:62001    (夜 ...