cdq分治+dp

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

这个代码是错的

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

不调了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = ;
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 = ;
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] = ;
}
} 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[], c[];
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) >> ;
while(f[mid].x == f[mid - ].x) --mid;
if(l > mid) return;
cdq(l, mid);
for(int i = l; i <= r; ++i) g[i] = f[i];
sort(f + l + , f + mid + , cpy);
sort(f + mid + , f + r + , cpy);
int i = l, j = mid + ;
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 - ) + );
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 + , r);
}
int main()
{
scanf("%lld%lld%d", &a, &p, &n);
ll p1 = a % p * a % p * a % p;
f[].id = ;
t[] = a % p;
t[] = a % p * a % p;
t[] = a % p * a % p * a % p;
for(int i = ; i <= ; ++i) c[i] = t[i];
sort(c + , c + );
f[].x = c[] * p1 % p;
f[].y = c[] * p1 % p;
f[].z = c[] * p1 % p;
vt.push_back(f[].z);
for(int i = ; i <= n; ++i)
{
t[] = t[] * p1 % p;
t[] = t[] * p1 % p;
t[] = t[] * p1 % p;
for(int j = ; j <= ; ++j) c[j] = t[j];
sort(c + , c + );
f[i].x = c[];
f[i].y = c[];
f[i].z = c[];
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 = ; i < vt.size(); ++i) mp[vt[i]] = i + ;
for(int i = ; i <= n; ++i) f[i].z = mp[f[i].z];
lim = vt.size();
sort(f + , f + n + , cpx);
cdq(, n);
printf("%d\n", ans);
return ;
}

bzoj2253的更多相关文章

  1. 【BZOJ2253】[2010 Beijing wc]纸箱堆叠 cdq分治

    [BZOJ2253][2010 Beijing wc]纸箱堆叠 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后,即可自动化生产三边边长为 ...

  2. BZOJ2253: [2010 Beijing wc]纸箱堆叠

    题解: 其实就是求三维偏序最长链.类似于三维逆序对,我们可以用树状数组套平衡树来实现. DP方程 :f[i]=max(f[j]+1) a[j]<a[i] 我们按一维排序,另一位建立树状数组,把第 ...

  3. BZOJ2253 2010 Beijing wc 纸箱堆叠 CDQ分治

    这题之前度娘上没有CDQ分治做法,gerwYY出来以后写了一个.不过要sort3遍,常数很大. gerw说可以类似划分树的思想优化复杂度,但是蒟蒻目前不会划分树(会了主席树就懒得去弄了). 嗯 将me ...

  4. bzoj2253 纸箱堆叠

    题目链接 题意 求三元组的严格上升子序列 思路 先考虑暴力\(dp\)一下 for(int i = 1;i <= n;++i) for(int j = 1;j < i;++j) if(x[ ...

  5. bzoj2253纸箱堆叠(动态规划+cdq分治套树状数组)

    Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 ...

  6. 【BZOJ2253】纸箱堆叠 [CDQ分治]

    纸箱堆叠 Time Limit: 30 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description P 工厂是一个生产纸箱的工厂. 纸 ...

  7. cdq分治(偏序)

    偏序问题: https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 优质题 ...

随机推荐

  1. 01Hypertext Preprocessor

    Hypertext Preprocessor PHP即Hypertext Preprocessor是一种被广泛使用的开放源代码多用途动态交互性站点的强有力的服务器端脚本语言尤其适用于 Web开发人员可 ...

  2. P1077摆花

    传送 总共要摆m盆花,而每种花最多有a[i]盆.仔细思索,发现它是一个多重背包求方案数问题.但是我蒟蒻的不会,于是跑去问大佬. 以下状态转移方程及化简from rqy 如果第i个物品有a[i],每个的 ...

  3. react 返回上一页

    import * as React from 'react' import { Layout } from 'antd'; import creatHistory from 'history/crea ...

  4. java学习日志--char和int的相互转换

    package shugen; /*ASCLL码表 * 48 数字0 * 49 1 * 50 2 * 51 3 * 52 4 * 53 5 * 54 6 * 55 7 * 56 8 * 57 9 */ ...

  5. 洛谷——P1850 换教室

    P1850 换教室 有 2n 节课程安排在 nn 个时间段上.在第 i个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 $c_i$​ 上课,而另一节课程在教室 $d_i$ ...

  6. TestNG套件测试(一)

    测试套件是用于测试软件程序的行为或一组行为的测试用例集合. 在TestNG中,我们无法在测试源代码中定义一个套件,但它可以由一个XML文件表示,可以灵活配置要运行的测试. 套件用<suite&g ...

  7. js获取昨天,最近7天,最近30天通用方法

    function formatDate (val) { // 格式化时间 let start = new Date(val) let y = start.getFullYear() let m = ( ...

  8. 【C++】实现记录软件计时时间

    利用getTickCount()和getTickFrequency()函数实现计时 double time0 = static_cast<double>(getTickCount()); ...

  9. SQL to MongoDB Mapping Chart

    http://docs.mongodb.org/manual/reference/sql-comparison/ In addition to the charts that follow, you ...

  10. [luoguP2858] [USACO06FEB]奶牛零食Treats for the Cows(DP)

    传送门 f[i][j][k] 表示 左右两段取到 i .... j 时,取 k 次的最优解 可以优化 k 其实等于 n - j + i 则 f[i][j] = max(f[i + 1][j] + a[ ...