列表

详情


NC52816. Pair-Pair

描述

Bobo is tired of all kinds of hard LIS (Longest Increasing Subsequence) problems,
so he decides to make himself some easier one.

Bobo has n pairs
where holds for all i.
He defines f(i, j) be the length of longest increasing subsequence of sequence .

It's clear that .
Bobo would like to know g(k) which is the number of pairs (i, j) where f(i, j) = k.

Note that a sequence labeled with is an increasing subsequence of only if:

*
*

输入描述

The input contains at most 30 sets. For each set:
The first line contains 2 integers n, m ().
The i-th of the following n lines contains 2 integers a_i, b_i ().

输出描述

For each set, 4 integers g(1), g(2), g(3), g(4).

示例1

输入:

2 4
1 2
3 4

输出:

0 3 0 1

示例2

输入:

2 1
1 1
1 1

输出:

4 0 0 0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 75ms, 内存消耗: 9988K, 提交时间: 2019-10-08 19:44:48

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 50;
ll up[1050], down[1050];
ll d[1050][1050];
int n, m;
int x[maxn], y[maxn];
ll ans[5];
int main(){
    cin>>n>>m;
    for(int i = 1; i <= n; ++i){
        scanf("%d%d", &x[i], &y[i]);
        if(x[i] < y[i]) up[y[i]]++;
        else down[y[i]]++;
        d[x[i]][y[i]]++;
    }
    for(int i = 1; i <= m; ++i){
        up[i] += up[i-1];
        down[i] += down[i-1];
        for(int j = 1; j <= m; ++j) d[i][j] += d[i-1][j] + d[i][j-1] - d[i-1][j-1];
    }
    for(int i = 1; i <= n; ++i){
        if(y[i] > x[i]){
            ans[4] += up[x[i]-1];
            ans[3] += up[y[i]-1] - up[x[i]-1] + down[x[i]-1];
            ans[3] += d[x[i]-1][m] - d[x[i]-1][y[i]-1];
        }
        else{
            ans[1] += down[m]-down[x[i]-1];
            ans[3] += up[x[i]-1];
        }
    }
    ll sum = (ll)n*n;
    ans[2] = sum-ans[1]-ans[3]-ans[4];
    for(int i = 1; i <= 4; ++i){
        if(i > 1) printf(" ");
        printf("%lld", ans[i]);
    }
}

C++14(g++5.4) 解法, 执行用时: 53ms, 内存消耗: 10312K, 提交时间: 2019-10-13 11:12:04

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 50;
ll up[1050], down[1050];
ll d[1050][1050];
int n, m;
int x[maxn], y[maxn];
ll ans[5];
int main(){
    cin>>n>>m;
    for(int i = 1; i <= n; ++i){
        scanf("%d%d", &x[i], &y[i]);
        if(x[i] < y[i]) up[y[i]]++;
        else down[y[i]]++;
        d[x[i]][y[i]]++;
    }
    for(int i = 1; i <= m; ++i){
        up[i] += up[i-1];
        down[i] += down[i-1];
        for(int j = 1; j <= m; ++j) d[i][j] += d[i-1][j] + d[i][j-1] - d[i-1][j-1];
    }
    for(int i = 1; i <= n; ++i){
        if(y[i] > x[i]){
            ans[4] += up[x[i]-1];
            ans[3] += up[y[i]-1] - up[x[i]-1] + down[x[i]-1];
            ans[3] += d[x[i]-1][m] - d[x[i]-1][y[i]-1];
        }
        else{
            ans[1] += down[m]-down[x[i]-1];
            ans[3] += up[x[i]-1];
        }
    }
    ll sum = (ll)n*n;
    ans[2] = sum-ans[1]-ans[3]-ans[4];
    for(int i = 1; i <= 4; ++i){
        if(i > 1) printf(" ");
        printf("%lld", ans[i]);
    }
}

上一题