码迷,mamicode.com
首页 > 其他好文 > 详细

D - Lis on Circle Gym - 102441D (LIS + 线段树)

时间:2019-12-05 22:43:19      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:www   ash   star   with   ever   style   ==   sequence   player   

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.

 

0mi1050≤∑mi≤105
1n1051≤n≤105
0k<n0≤k<n
0x1090≤x≤109

 

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

Input
3 1
4 1 10 12 20
2 11 21
4 3 5 15 22
Output
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 + 1010;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;

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<<2];
void pushup(int rt){
  tree[rt] = max(tree[rt*2],tree[rt*2+1]);
}
void build(int l,int r,int rt){
  if(l == r){
    tree[rt] = pi(0,-1);
    return ;
  }
  int mid = (l + r) / 2;
  build(l,mid,rt*2);
  build(mid + 1,r,rt*2+1);
  pushup(rt);
}
pi query(int L,int R,int l,int r,int rt){//询问[L,R]内长度最长的上升子序列节点
  if(L > R)return pi(0,-1);
  if(L <= l && r <= R){
    return tree[rt];
  }
  int mid = (l + r) / 2;
  pi ans = pi(0,-1);
  if(L <= mid)ans = max(ans,query(L,R,l,mid,rt*2));
  if(R >  mid)ans = max(ans,query(L,R,mid+1,r,rt*2+1));
  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) / 2;
  if(pos <= mid)update(pos,val,l,mid,rt*2);
  else update(pos,val,mid+1,r,rt*2+1);
  pushup(rt);
}
void dfs(int u,int dep){//dfs寻找路径,dp[u].second 代表下一个下标是几
  if(u == -1){
    cout << dep << endl;
    return ;
  }
  dfs(dp[u].second,dep+1);
  cout << arr[u].id <<   << arr[u].x << endl;
}
int main()
{
  int n,k,top = 0;
  cin >> n >> k;
  build(1,n,1);
  rep(i,1,n){
    int m;
    cin >> m;
    rep(j,1,m){
      int x;
      cin >> x;
      arr[++top] = (node){i,x};
    }
  }
  sort(arr+1,arr+1+top);
  int i;
  for(i = 1;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 - 2) % n + n) % n + 1;//最多可跳过k个,这个推一下就好了~
      if(pos < id)dp[j] = query(pos,id-1,1,n,1);
      else dp[j] = max(query(pos,n,1,n,1),query(1,id-1,1,n,1)); 
    }
    int j;
    for(j = i;j <= top;j++){
      if(arr[i].x != arr[j].x)break;
      if(dp[j].first == 0 && arr[j].id > k + 1)continue;//第一个人特判
      dp[j].first++;//以j为结尾的最长上升子序列加1
      int pos = arr[j].id;
      update(pos,pi(dp[j].first,j),1,n,1);//更新最优值
    }
    i = j;
  }
  int ans = 0,rt = 0;
  for(int i = 1;i <= top;i++){
    if(dp[i].first > ans){
      ans = dp[i].first;
      rt = i;
    }
  }
  if(rt == 0)cout << 0 << endl;
  else dfs(rt,0);
  return 0;
}
/*
3 0
3 1 2 3
3 1 2 1
4 1 2 3 2
*/
View Code

 

D - Lis on Circle Gym - 102441D (LIS + 线段树)

标签:www   ash   star   with   ever   style   ==   sequence   player   

原文地址:https://www.cnblogs.com/cherish-lin/p/11991879.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!