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个位置,此时数列为 ...
随机推荐
- 十二、JavaScript之变量申明
一.代码如下 二.运行效果如下 <!DOCTYPE html> <html> <meta http-equiv="Content-Type" cont ...
- bool之regexp正则注入(原理详解)
感谢原创博主的文章,在此致敬.本文转自:http://www.cnblogs.com/lcamry/articles/5717442.html 我们都已经知道,在MYSQL 5+中 informati ...
- ISO处理jq事件
jq事件在IOS上,如果标签本身不具备某些功能,而我们通过document或者body绑定上去的话,有些事件是不起作用的,同时在IOS上jq事件也存在延迟. 事件不起作用 这里点击事件为例,在IOS中 ...
- Node.js 发送Email
章节 Node.js 介绍 Node.js 入门 Node.js 模块 Node.js HTTP模块 Node.js 文件系统模块 Node.js URL模块 Node.js NPM Node.js ...
- HDU - 4082 Hou Yi's secret
题意:射箭落在n个点,任取三点可构成一个三角形,问最大的相似三角形集(一组互相相似的三角形)的个数. 分析: 1.若n个点中有相同的点,要去重,题目中说射箭会形成洞,任选三个洞构成三角形,因此射在同一 ...
- 重新修改AD中PCB的形状快捷键
Altium Designer 快速修改板子形状为Keep-out layer大小 1,切换到 Keep-out layer层, 2,选择层,快捷键为S+Y: 3,设计-板子形状-按照选择 ...
- 读书笔记 - js高级程序设计 - 第十二章 DOM2和DOM3
Node类型的变化 访问元素的样式 myDiv.style.backgroundColor = "red" myDiv.style.width = "100px& ...
- 大二暑假第一周总结--初次安装配置Hadoop
本次配置主要使用的教程:http://dblab.xmu.edu.cn/blog/install-hadoop-in-centos/ 以下是自己在配置中的遇到的一些问题和解决方法,或者提示 一.使用虚 ...
- 51Nod-1072-威佐夫游戏
有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取.拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出2堆石子的数量, ...
- 201803-2 碰撞的小球 Java
思路: 直接按照题意模拟,感觉没什么太好的办法.另外注意:int这种基础数据类型不能用equals这个方法 ,必须是Integer类型 import java.util.Scanner; public ...