HDU5773-The All-purpose Zero-多校#41010-最长上升子序列问题
只想到了朴素的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-最长上升子序列问题的更多相关文章
- 牛客多校第五场 G subsequence 1 最长公共子序列/组合数
题意: 给定两个由数字组成的序列s,t,找出s所有数值大于t的子序列.注意不是字典序大. 题解: 首先特判s比t短或一样长的情况. 当s比t长时,直接用组合数计算s不以0开头的,长度大于t的所有子序列 ...
- Contest2071 - 湖南多校对抗赛(2015.03.28)
Contest2071 - 湖南多校对抗赛(2015.03.28) 本次比赛试题由湖南大学ACM校队原创 http://acm.csu.edu.cn/OnlineJudge/contest.php?c ...
- 2014哈商大ICPC/ACM校赛解题报告
被debug邀请去參加校赛,哎,被虐..我对不起工大.. 由于本人不搞ACM,算法处于HelloWorld水准.. 虽然题目除了鸟不拉屎星人之外都非常水,但我能做到这个程度,全然是超水平发挥了.. 数 ...
- 2017 多校4 Security Check
2017 多校4 Security Check 题意: 有\(A_i\)和\(B_i\)两个长度为\(n\)的队列过安检,当\(|A_i-B_j|>K\)的时候, \(A_i和B_j\)是可以同 ...
- hdu6078[优化递推过程] 2017多校4
这道题一眼看过去好像和最长公共子序列有点像. 一开始只想到暴力的推法, 令dp[i][j][k]表示 a[i]=b[j](即以ai,bj为结尾的波浪序列的方案数), 且最终状态为k(0,1分别代表下降 ...
- 蒟蒻ACMer回忆录 · 一段弱校ACM的奋斗史
三年半的ACM生涯终于迎来了终点,退役之时,感慨万分,故写此文以纪念逝去的时光,那些为ACM拼搏的日子,那段弱校ACM的奋斗史. 三年半的ACM生涯,窝见证了CUMT从打铁到铜牌的突破,又见证了从铜牌 ...
- 2015 GDUT校赛
周末打了个GDUT的校赛,也是作为SCAU的一场个人排位. 比赛中竟然卡了个特判,1个半钟就切了5条了,然后一直卡. 还有其他两条可以做的题也没法做了,性格太执着对ACM来说也是错呀. 讲回正题 . ...
- HDU4512完美队形I && HDU1423 Greatest Common Increasing Subsequence (LCIS)
填坑的时候又到啦,校赛因为不会LCIS所以吃了大亏,这里要补起来.LCIS就是在两个串里找最长上升子序列,相关的博客有很多,这里自己就不写那么多了. http://www.cnblogs.com/ja ...
- Codeforces245H - Queries for Number of Palindromes(区间DP)
题目大意 给定一个字符串s,q个查询,每次查询返回s[l-r]含有的回文子串个数(题目地址) 题解 和有一次多校的题目长得好相似,这个是回文子串个数,多校的是回文子序列个数 用dp[i][j]表示,s ...
随机推荐
- outlook署名最后一行没换行
Outlook のプレーン テキスト形式での投稿で改行が削除されます 1.通过更改outlook默认设置可以解决 https://support.microsoft.com/ja-jp/help/28 ...
- Spring Boot 中使用 @Transactional 注解配置事务管理
事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持.Spring 事务管理分为编程式和声明式的两种方式.编程式事务指的是通过编码方式实现事务:声明式事务基于 AOP ...
- Linux之查看系统配置命令
1.查看CPU个数: [root@ifusion ~]# lscpu 2.查看CPU进程数.核数: [root@ifusion ~]# cat /proc/cpuinfo 3.查看内存总量: [roo ...
- from、where、group、with、having、order、union、limit 的使用
顺序很重要 每次看数据库的一些语法时,都很自然的略过那一大堆的规则,比如说线下面这段select的语法: select [field1,field2...] func_namefrom table1, ...
- Velocity ${} 和$!{}、!${}区别
前言 在使用Velocity时经常会看到三种使用变量的情况 情况一:${name} 情况二:$!{name} 情况三:!${name} 那么三者之间到底有什么区别呢?莫慌!!!哈哈 情况一:${nam ...
- webservice服务的提供及调用完整代码示例
服务提供方: applicationContext.xml applicationContext-webService.xml 服务调用方:
- vue上传图片到服务器
https://blog.csdn.net/qq_29712995/article/details/78839093(copy) HTML代码: <input accept="imag ...
- day 7-19 Mysql索引原理与查询优化
一,介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语 ...
- 想在已创建的Vue工程里引入vux组件
<1>. 在项目里安装vux npm install vux --save <2>. 安装vux-loader (这个vux文档似乎没介绍,当初没安装结果报了一堆错误) npm ...
- PMP三点
三点估算:悲观36天,可能21天,乐观6天.在16至26天内完成的概率是多少?这个算法是PERT估算最终估算结果=(悲观工期+乐观工期+4×最可能工期)/6=(36+6++4*21)/6=21标准差= ...