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 ...
随机推荐
- java的instanceof关键字
java 中的instanceof 运算符是用来判断对象是否是 特定类或这个特定类的子类 的一个实例. 用法: result = object instanceof class 参数: Result: ...
- hdu5943素数间隙与二分匹配
题意: 给出n和s,匹配(s+1,s+2,s+3......s+n)和(1,2,3,4,5........n)让(s+x)%x==0,判断是否有解 思路: 先用程序跑一边,发现1到1e9得素数间隙小于 ...
- poj3468 线段树的懒惰标记
题目链接:poj3468 题意:给定一段数组,有两种操作,一种是给某段区间加c,另一种是查询一段区间的和 思路:暴力的方法是每次都给这段区间的点加c,查询也遍历一遍区间,复杂度是n*n,肯定过不去,另 ...
- JS XMLHttpRequesst对象 http post的五种请求状态
记录一下js中对http请求的几种状态,下附代码 readyState 存有 XMLHttpRequest 的状态.从 0 到 4 发生变化. 0: 请求未初始化 1: 服务器连接已建立 2: 请求已 ...
- Windows 激活的简单办法(能上网)
1. 之前很多机器上面总是提示我 盗版系统看起来挺不high的 2. 还是使用之前的办法来进行激活 slmgr (之前写过) /ipk <Product Key> 安装产品密钥(替换现 ...
- 逻辑斯特回归tensorflow实现
calss #!/usr/bin/python2.7 #coding:utf-8 from __future__ import print_function import tensorflow as ...
- Vagrant系列(二)----Vagrant的配置文件Vagrantfile详解
一.简介 在我们的工作目录下有一个Vagrantfile文件,里面包含有大量的配置信息,通过它可以定义虚拟机的各种配置,如网络.内存.主机名等,主要包括三个方面的配置,虚拟机的配置.SSH配置.Vag ...
- Angular 自定义过滤器
<!DOCTYPE html><html ng-app="myApp"><head lang="en"> <meta ...
- wiki 安装
地址:https://www.jianshu.com/p/fb2574567eae
- Java权限访问修饰符
私有的,以 private 修饰符指定,在同一类内可见. 默认的,也称为 default,在同一包内可见,不使用任何修饰符. 受保护的,以 protected 修饰符指定,对同一包内的类和所有子类可见 ...