bzoj2253

cdq分治+dp

看见三维偏序是cdq,互相包含是最长上升子序列

这个代码是错的

交了两份代码,发现手动出数据是不一样的。。。

不调了

#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;
}
View Code

 

posted @ 2017-07-19 19:23  19992147  阅读(199)  评论(0编辑  收藏  举报