D - Lis on Circle Gym - 102441D (LIS + 线段树)
There are nn people at the round gaming table. Each of them has a set of cards. Every card contains some number xx. Players make turns consecutively, one after another, starting from the player number 1. A player in his turn can either skip his turn (to pass), or put (and leave on the table) a card with a number that is strictly greater than the previously played last number. No more than kk players in a row can pass the turn. All players know the numbers written on the other players cards and always play optimally. Help gamblers to assemble an increasing sequence of maximum length.
Input
The first line contains two numbers nn and kk — the number of players and the maximum possible amount of turn skipping in a row.
The next nn lines contain the description of the cards players have in their hands. The first number in the mimi is the number of cards the current player has in his hand. The following space separated miminumbers represent the written on the cards numbers xx.
Output
In the first line print the single number — the length of the maximum sequence. In the next lines print two space separated numbers: the player index number and the number written on the card he played. If several solutions exist, output any of them.
Example
3 1
4 1 10 12 20
2 11 21
4 3 5 15 22
9
1 1
3 3
1 10
2 11
1 12
3 15
1 20
2 21
3 22
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define bep(i, a, b) for(int i = a; i >= b; i--)
#define lowbit(x) (x&(-x))
#define MID (l + r) / 2
#define ls pos*2
#define rs pos*2+1
#define pb push_back
#define ios() ios::sync_with_stdio(0) using namespace std;
typedef pair<int,int>pi;
const int maxn = 1e5 + ;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + ; struct node{
int id,x;
bool operator < (const node & w)const{
return x < w.x || (x == w.x && id < w.id);
}
}arr[maxn];
pi dp[maxn],tree[maxn<<];
void pushup(int rt){
tree[rt] = max(tree[rt*],tree[rt*+]);
}
void build(int l,int r,int rt){
if(l == r){
tree[rt] = pi(,-);
return ;
}
int mid = (l + r) / ;
build(l,mid,rt*);
build(mid + ,r,rt*+);
pushup(rt);
}
pi query(int L,int R,int l,int r,int rt){//询问[L,R]内长度最长的上升子序列节点
if(L > R)return pi(,-);
if(L <= l && r <= R){
return tree[rt];
}
int mid = (l + r) / ;
pi ans = pi(,-);
if(L <= mid)ans = max(ans,query(L,R,l,mid,rt*));
if(R > mid)ans = max(ans,query(L,R,mid+,r,rt*+));
return ans;
}
void update(int pos,pi val,int l,int r,int rt){//pos位置更改最优值(和自身取最优值)
if(l == r){
tree[rt] = max(tree[rt],val);
return ;
}
int mid = (l + r) / ;
if(pos <= mid)update(pos,val,l,mid,rt*);
else update(pos,val,mid+,r,rt*+);
pushup(rt);
}
void dfs(int u,int dep){//dfs寻找路径,dp[u].second 代表下一个下标是几
if(u == -){
cout << dep << endl;
return ;
}
dfs(dp[u].second,dep+);
cout << arr[u].id << ' ' << arr[u].x << endl;
}
int main()
{
int n,k,top = ;
cin >> n >> k;
build(,n,);
rep(i,,n){
int m;
cin >> m;
rep(j,,m){
int x;
cin >> x;
arr[++top] = (node){i,x};
}
}
sort(arr+,arr++top);
int i;
for(i = ;i <= top;){
for(int j = i;j <= top;j++){//一个值的数据有多个的话,处理完,先不更新,因为题目保证严格递增
if(arr[i].x != arr[j].x)break;
int id = arr[j].id;
int pos = ((id - k - ) % n + n) % n + ;//最多可跳过k个,这个推一下就好了~
if(pos < id)dp[j] = query(pos,id-,,n,);
else dp[j] = max(query(pos,n,,n,),query(,id-,,n,));
}
int j;
for(j = i;j <= top;j++){
if(arr[i].x != arr[j].x)break;
if(dp[j].first == && arr[j].id > k + )continue;//第一个人特判
dp[j].first++;//以j为结尾的最长上升子序列加1
int pos = arr[j].id;
update(pos,pi(dp[j].first,j),,n,);//更新最优值
}
i = j;
}
int ans = ,rt = ;
for(int i = ;i <= top;i++){
if(dp[i].first > ans){
ans = dp[i].first;
rt = i;
}
}
if(rt == )cout << << endl;
else dfs(rt,);
return ;
}
/*
3 0
3 1 2 3
3 1 2 1
4 1 2 3 2
*/
D - Lis on Circle Gym - 102441D (LIS + 线段树)的更多相关文章
- cf1132G 线段树解分区间LIS(一种全新的线段树解LIS思路)+单调栈
/* 给定n个数的数列,要求枚举长为k的区间,求出每个区间的最长上升子序列长度 首先考虑给定n个数的数列的LIS求法:从左往右枚举第i点作为最大点的贡献, 那么往左找到第一个比a[i]大的数,设这个数 ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- Gym 101201J Shopping (线段树+取模)
题意:给定 n 个物品,然后有 m 个人买东西,他们有 x 元钱,然后从 l - r 这个区间内买东西,对于每个物品都尽可能多的买,问你最少剩下多少钱. 析:对于物品,尽可能多的买的意思就是对这个物品 ...
- Hacker Cups and Balls Gym - 101234A 二分+线段树
题目:题目链接 题意:有编号从1到n的n个球和n个杯子. 每一个杯子里有一个球, 进行m次排序操作,每次操作给出l,r. 如果l<r,将[l,r]范围内的球按升序排序, 否则降序排, 问中间位置 ...
- Gym - 101982F 扫描线+线段树
题目链接:https://codeforces.com/gym/101982/attachments 要你求覆盖奇数次的矩形面积并,每次更新时减去原先的值即可实现奇数次有效,下推时为保证线段长度不变左 ...
- 洛谷P3928 Sequence2(dp,线段树)
题目链接: 洛谷 题目大意在描述底下有.此处不赘述. 明显是个类似于LIS的dp. 令 $dp[i][j]$ 表示: $j=1$ 时表示已经处理了 $i$ 个数,上一个选的数来自序列 $A[0]$ 的 ...
- Hdu 3564 Another LIS 线段树+LIS
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- HDU3564 --- Another LIS (线段树维护最值问题)
Another LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- hdu_3564_Another LIS(线段树+LIS)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3564 题意:给你N个数的位置.数i的位置为第i个数,比如 0 0 2,表示1插在第0个位置,此时数列为 ...
随机推荐
- servlet的基本类和接口
javax.servlet.Servlet接口 javax.servlet.GenericServlet类(协议无关版本) javax.servlet.http.HttpServlet类(HTTP版本 ...
- echarts 柱状图的选中模式实现-被选中变色和再次选中为取消变色
方法: function barCharShow(curr_dim,divId,result_data){ mutilDim(curr_dim);//维度信息 var paint = initEcha ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 多线程
多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序.一般情况下,两种类型的多任务处理:基于进程和基于线程. 基于进程的多任务处理是程序的并发执行. 基于线程的多任务处理 ...
- junit基础学习之-简介(1)
JUnit介绍 JUnit是一个开源的Java单元测试框架,由 Erich Gamma 和 Kent Beck 开发完成. 1 JUnit简介 JUnit主要用来帮助开发人员进行Java的单元测试, ...
- POJ 2632:Crashing Robots
Crashing Robots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8424 Accepted: 3648 D ...
- java初学小项目-酒店客房管理系统
最近初次接触JAVA,感觉之前学的C语言很有用,跟着视频做了一个小项目-酒店客房管理系统 /* 酒店客房管理系统 */ import java.util.Scanner;//通过键盘来输入命令需要的引 ...
- QF中间件
QF中间件使用说明 QF中间件是在2020年春节期间出现新型冠状病毒感染的肺炎疫情不敢外出,闲来无事编写的.编程是业余爱好,平时编程只会拖控件,中间件可能存在未知Bug,这个版本也只 ...
- 【新年呈献】高性能网络通信框架 HP-Socket v5.7.1
项目主页 : http://www.oschina.net/p/hp-socket 开发文档 : https://www.docin.com/p-2287339564.html 下载地址 : http ...
- Linux笔记01
linux目录结构 : linux只有一个目录. usr:等价于programfiles: etc:存放系统配置 root:管理员(超级用户)目录, home:存放其他用户的目录: lib:共享包: ...
- 吴裕雄--天生自然 JAVASCRIPT开发学习:条件语句
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...