bzoj2253
cdq分治+dp
看见三维偏序是cdq,互相包含是最长上升子序列
这个代码是错的
交了两份代码,发现手动出数据是不一样的。。。
不调了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 50010; int n, lim, ans; struct BIT { int tree[N]; int lowbit(int i) { return i & (-i); } void update(int pos, int delta) { for(int i = pos; i <= lim; i += lowbit(i)) tree[i] = max(tree[i], delta); } int query(int pos) { int ret = 0; for(int i = pos; i; i -= lowbit(i)) ret = max(ret, tree[i]); return ret; } void clr(int pos) { for(int i = pos; i <= lim; i += lowbit(i)) tree[i] = 0; } } tr; struct data { ll x, y, z; int type, id; } f[N], g[N]; ll a, p; map<ll, int> mp; vector<ll> vt; ll t[4], c[4]; int dp[N]; bool cpx(data A, data B) { if(A.x == B.x) { if(A.y == B.y) return A.z < B.z; else return A.y < B.y; } return A.x < B.x; } bool cpy(data A, data B) { return A.y == B.y ? A.z < B.z : A.y < B.y; } void cdq(int l, int r) { if(l >= r) return; int mid = (l + r) >> 1; while(f[mid].x == f[mid - 1].x) --mid; if(l > mid) return; cdq(l, mid); for(int i = l; i <= r; ++i) g[i] = f[i]; sort(f + l + 1, f + mid + 1, cpy); sort(f + mid + 1, f + r + 1, cpy); int i = l, j = mid + 1; while(j <= r) { while(i <= mid && f[i].y < f[j].y) { tr.update(f[i].z, dp[f[i].id]); ++i; } dp[f[j].id] = max(dp[f[j].id], tr.query(f[j].z - 1) + 1); ans = max(ans, dp[f[j].id]); ++j; } for(int i = l; i <= mid; ++i) tr.clr(f[i].z); for(int i = l; i <= r; ++i) f[i] = g[i]; cdq(mid + 1, r); } int main() { scanf("%lld%lld%d", &a, &p, &n); ll p1 = a % p * a % p * a % p; f[1].id = 1; t[1] = a % p; t[2] = a % p * a % p; t[3] = a % p * a % p * a % p; for(int i = 1; i <= 3; ++i) c[i] = t[i]; sort(c + 1, c + 4); f[1].x = c[1] * p1 % p; f[1].y = c[2] * p1 % p; f[1].z = c[3] * p1 % p; vt.push_back(f[1].z); for(int i = 2; i <= n; ++i) { t[1] = t[1] * p1 % p; t[2] = t[2] * p1 % p; t[3] = t[3] * p1 % p; for(int j = 1; j <= 3; ++j) c[j] = t[j]; sort(c + 1, c + 4); f[i].x = c[1]; f[i].y = c[2]; f[i].z = c[3]; f[i].id = i; vt.push_back(f[i].z); } sort(vt.begin(), vt.end()); vt.erase(unique(vt.begin(), vt.end()), vt.end()); for(int i = 0; i < vt.size(); ++i) mp[vt[i]] = i + 1; for(int i = 1; i <= n; ++i) f[i].z = mp[f[i].z]; lim = vt.size(); sort(f + 1, f + n + 1, cpx); cdq(1, n); printf("%d\n", ans); return 0; }