題意
- 一個平面直角座標系上,有個點,標號爲到,其中第個點的座標爲,求滿足以下兩個條件的點列的數目(假設的長度爲),一是對任意,必有 > ;二是對任意,必有或者。求滿足條件的非空序列的數目,結果對一個整數取模。
對於第一個限制很容易會想到對進行排序,但是這樣子空間是的,過不了這個卡空間的題,那麼我們考慮對進行排序。
設爲號點起始,向左或向右延伸的方案數,那麼我們每次添加一個新點一定是橫座標最大的,那麼它只能放在第一個或者第二個,那麼我們枚舉這個點前面的點,如果它的縱座標小於當前新加的點,那麼當前點就是第一個點,我們把枚舉點右邊的點全部加入當前點的左邊,如果它的縱座標大於當前新加的點,枚舉點就是第一個點,我們把當前點左邊的點全部加入枚舉點的右邊,時間複雜度,空間複雜度。
#include<bits/stdc++.h>
#define file(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define For(i, a, b) for(register int i = (a), i##_end_ = (b); i <= i##_end_; ++ i)
#define FOR(i, a, b) for(register int i = (a), i##_end_ = (b); i >= i##_end_; -- i)
#define debug(x) cout << #x << " = " << x << endl
#define mem(a, b) memset(a, b, sizeof(a))
#define cpy(a, b) memcpy(a, b, sizeof(a))
#define min(a, b) (a < b ? a : b)
#define max(a, b) (b < a ? a : b)
#define inf (0x3f3f3f3f)
#define INF (1e18)
#define pb push_back
#define mp make_pair
#define x first
#define y second
typedef unsigned long long ull;
typedef unsigned int uint;
typedef long long ll;
typedef std::pair<ll, int> PLI;
typedef std::pair<int, int> PII;
typedef long double ldb;
typedef double db;
template<class T>inline bool chkmax(T &_, T __) {return _ < __ ? _ = __, 1 : 0;}
template<class T>inline bool chkmin(T &_, T __) {return _ > __ ? _ = __, 1 : 0;}
using namespace std;
const int N = 7e3 + 10;
int f[N][2], n, ans, mod;
struct Point {
int x, y;
bool operator < (const Point &T) const {
return x < T.x;
}
}A[N];
int main() {
#ifdef ylsakioi
file("refract");
#endif
scanf("%d%d", &n, &mod); For(i, 1, n) scanf("%d%d", &A[i].x, &A[i].y);
ans = mod - n; sort(A + 1, A + n + 1);
For(i, 1, n) {
f[i][0] = f[i][1] = 1;
FOR(j, i - 1, 1) {
if(A[i].y > A[j].y) (f[i][0] += f[j][1]) %= mod;
if(A[j].y > A[i].y) (f[j][1] += f[i][0]) %= mod;
}
}
For(i, 1, n) (ans += (f[i][0] + f[i][1]) % mod) %= mod;
cout << ans << endl;
return 0;
}