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 ...
随机推荐
- COMCMS v0.9 版本发布,带前后端的一个响应式企业站
前言:踏入十二月,人生也即将进入下一个阶段. 最近忙于其他,代码也是偶尔更新.目前算是0.9的版本,就是基本上可以完成一个简单的企业站/博客的功能. 主要特点:前台完整演示:文章.产品.留言.界面响应 ...
- node express使用
var express = require('express'); var app = express(); app 对象具有以下的方法: 路由HTTP请求:app.METHOD和app.param. ...
- PySpider框架的基本用法
pyspider安装: 3.7之后无法正常使用,使用可以下载Python3.6或以下,或者修改pyspider内部代码 ———————————————————————————————————————— ...
- python学习第十篇——while 的灵活运用
sandwiches_orders = ['apple','banana','mango',"apple","watermelon"] finished_san ...
- (第十三周)Final阶段成员贡献分
项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 个人贡献分=基础分+表现分 基础分=5*5*0.5/5=2.5 成员得分如下: 成员 基础分 表现分 个人贡献 ...
- linux中根据名称kill进程
shell函数如下: # kill processes by name kbn() { line=`ps -a | grep $1` arr=($line) for((i=0;i<${#arr[ ...
- 自己用习惯的idea快捷键笔记
Ctrl + Space 自动完成(win10下冲突不能用,自己换成 Alt + \ ) 切换方法是菜单中依次打开 file -> settings -> keymap,搜索complet ...
- day 7-2 multiprocessing开启多进程
一. multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu\_count\(\)查看),在python中大部分情况需要使用多 ...
- Day1 基础知识
数据类型,字符编码 二进制: 定义:二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”.当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是 ...
- Socket和ObjectOutputStream问题
用到Socket序列化对象网络传输时ObjectOutputStream一直刷新连接 用户代码 package com.jachs.ladflower.ladflower; import java.n ...