luogu4849 寻找宝藏 (cdq分治+dp)
设f[i]是已经走到i号点的值。
先要给第四维离散化、然后去重
第一维排序,第二维cdq分治,第三维cdq分治,第四维树状数组,找到满足j(x,y,z,w)<=i(x,y,z,w)的j,给i统计答案就可以。
然后在做的时候可以直接统计左区间内部答案、统计左区间给右区间造成的答案,但是一定要在这两个做完以后再统计右区间内部的答案,因为用右区间的某个j去更新i时,那个j是会被前面的区间影响的
然后就被卡常了QAQ...分治里一定要写尽量少的sort啊...
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
#define LL long long int
#define inf 0x3f3f3f3f
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int maxn=,mod=; LL rd(){
LL x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Node{
int x,y,z,w,i;
LL v;bool b;
}tmp1[maxn],tmp2[maxn],tmp3[maxn],arr1[maxn];
int N,M,mv[maxn],fv[maxn];
LL ma[maxn],fa[maxn];
const int sizN=sizeof(Node); inline void change(int x,LL y,int z){
if(z==){
while(x&&x<=M) ma[x]=mv[x]=,x+=lowbit(x);
return;
}
while(x&&x<=M){
if(ma[x]<y) ma[x]=y,mv[x]=z;
else if(ma[x]==y) mv[x]=(mv[x]+z)%mod;
else break;
x+=lowbit(x);
}
}
inline LL querya(int x){
LL re=;while(x) re=max(re,ma[x]),x-=lowbit(x);return re;
}
inline int queryv(int x){
int re=;LL a=;
while(x){
if(ma[x]>a) re=mv[x],a=ma[x];
else if(ma[x]==a) re=(re+mv[x])%mod;
x-=lowbit(x);
}return re;
} inline bool cmpw(Node a,Node b){return a.w<b.w;}
inline bool cmpz(Node a,Node b){
return a.z==b.z?cmpw(a,b):a.z<b.z;
}
inline bool cmpy(Node a,Node b){
return a.y==b.y?cmpz(a,b):a.y<b.y;
}
inline bool cmpx(Node a,Node b){
return a.x==b.x?cmpy(a,b):a.x<b.x;
} void cdq2(int l,int r){
if(l>=r) return;
//printf("!%d %d\n",l,r);
int m=l+r>>,p=l,q=m+,t=l;
cdq2(l,m);sort(tmp1+l,tmp1+m+,cmpz);
memcpy(tmp3+m+,tmp1+m+,sizN*(r-m));sort(tmp1+m+,tmp1+r+,cmpz);
while(p<=m&&q<=r){
if(tmp1[p].z<=tmp1[q].z){
if(!tmp1[p].b){
change(tmp1[p].w,fa[tmp1[p].i],fv[tmp1[p].i]);
}p++;
}else{
if(tmp1[q].b){
LL a=querya(tmp1[q].w)+tmp1[q].v;int v=queryv(tmp1[q].w);
if(v){
if(a>fa[tmp1[q].i]) fa[tmp1[q].i]=a,fv[tmp1[q].i]=v;
else if(a==fa[tmp1[q].i]) fv[tmp1[q].i]=(fv[tmp1[q].i]+v)%mod;
}
}
q++;
}
}while(q<=r){
if(tmp1[q].b){
LL a=querya(tmp1[q].w)+tmp1[q].v;int v=queryv(tmp1[q].w);
if(v){
if(a>fa[tmp1[q].i]) fa[tmp1[q].i]=a,fv[tmp1[q].i]=v;
else if(a==fa[tmp1[q].i]) fv[tmp1[q].i]=(fv[tmp1[q].i]+v)%mod;
}
}
q++;
}for(int i=l;i<p;i++) change(tmp1[i].w,,);
memcpy(tmp1+m+,tmp3+m+,sizN*(r-m));cdq2(m+,r);
} void cdq1(int l,int r){
if(l>=r) return;
int m=l+r>>,p=l,q=m+,t=l;
cdq1(l,m);sort(arr1+l,arr1+m+,cmpy);
memcpy(tmp2+m+,arr1+m+,sizN*(r-m));sort(arr1+m+,arr1+r+,cmpy);
while(p<=m&&q<=r){
if(arr1[p].y<=arr1[q].y){
tmp1[t]=arr1[p++];tmp1[t].b=;
}else{
tmp1[t]=arr1[q++];tmp1[t].b=;
}t++;
}while(p<=m) tmp1[t]=arr1[p++],tmp1[t++].b=;
while(q<=r) tmp1[t]=arr1[q++],tmp1[t++].b=;
cdq2(l,r);
memcpy(arr1+m+,tmp2+m+,sizN*(r-m));cdq1(m+,r);
} int main(){
//freopen("xzbz.in","r",stdin);
int i,j,k;
N=rd(),M=rd();
for(i=;i<=N;i++){
tmp1[i].i=i;tmp1[i].x=rd();tmp1[i].y=rd();
tmp1[i].z=rd();tmp1[i].w=rd();tmp1[i].v=rd();
}sort(tmp1+,tmp1+N+,cmpw);
for(i=,j=;i<=N;i++){
tmp2[i]=tmp1[i];
if(tmp1[i].w==tmp1[i-].w) tmp2[i].w=j;
else tmp2[i].w=++j;
}M=j;
sort(tmp2+,tmp2+N+,cmpx);
for(i=,j=;i<=N;i++){
if(tmp2[i].x==tmp2[i-].x&&tmp2[i].y==tmp2[i-].y&&tmp2[i].z==tmp2[i-].z&&tmp2[i].w==tmp2[i-].w){
arr1[j].v=(arr1[j].v+tmp2[i].v)%mod;
fa[j]=arr1[j].v;
}else{
arr1[++j]=tmp2[i];arr1[j].i=j;
fa[j]=arr1[j].v;fv[j]=;
}
}N=j;
cdq1(,N);
LL a=;int v=;
for(i=;i<=N;i++){
if(fa[i]>a) a=fa[i],v=fv[i];
else if(fa[i]==a) v=(v+fv[i])%mod;
}printf("%lld\n%d",a,v);
return ;
}
luogu4849 寻找宝藏 (cdq分治+dp)的更多相关文章
- BZOJ 2225: [Spoj 2371]Another Longest Increasing (CDQ分治+dp)
题面 Description 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. Input Output ...
- [BZOJ4700]适者(CDQ分治+DP/李超线段树)
如果没有秒杀,就是经典的国王游戏问题,按t/a从小到大排序即可. 考虑删除两个数i<j能给答案减少的贡献:S[i]*T[i]+P[i-1]*A[i]-A[i]+S[j]*T[j]+P[j-1]* ...
- cdq分治(偏序)
偏序问题: https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen 优质题 ...
- 51Nod1376 (dp + BIT // cdq分治)
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376 求LIS的数量. 乍一看觉得还是dp,仔细一看确实可以用dp做. ...
- HDU5322 Hope(DP + CDQ分治 + NTT)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...
- 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 3396 Solved: 1434[Submit][Sta ...
- 斜率dp cdq 分治
f[i] = min { f[j] + sqr(a[i] - a[j]) } f[i]= min { -2 * a[i] * a[j] + a[j] * a[j] + f[j] } + a[i] * ...
- bzoj 2244 [SDOI2011]拦截导弹(DP+CDQ分治+BIT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2244 [题意] 给定n个二元组,求出最长不上升子序列和各颗导弹被拦截的概率. [思路] ...
- BZOJ 2726: [SDOI2012]任务安排( dp + cdq分治 )
考虑每批任务对后面任务都有贡献, dp(i) = min( dp(j) + F(i) * (T(i) - T(j) + S) ) (i < j <= N) F, T均为后缀和. 与j有关 ...
随机推荐
- [Spark][Python]groupByKey例子
Spark Python 索引页 [Spark][Python]sortByKey 例子 的继续: [Spark][Python]groupByKey例子 In [29]: mydata003.col ...
- virtual box问题记录
1.已存在的虚拟机打开错误,可能是版本不一样的问题,我5.2.16版本,原虚拟机所属版本为4.3.12,换回4.3.12版本virtual box即可.
- Python 学习 第八篇:函数2(参数、lamdba和函数属性)
函数的参数是参数暴露给外部的接口,向函数传递参数,可以控制函数的流程,函数可以0个.1个或多个参数:在Python中向函数传参,使用的是赋值方式. 一,传递参数 参数是通过赋值来传递的,传递参数的特点 ...
- LDAP-openldap服务部署和测试(YUM安装)
1. 概述2. 服务端部署过程2.1 软件包说明2.2 部署过程2.3 配置过程3. 测试4. 生成LDIF格式文件4.1 安装migrationtools工具4.2 用migrationtools生 ...
- 转:SpringMVC之类型转换Converter(GenericConverter)
转: http://blog.csdn.net/fsp88927/article/details/37692215 SpringMVC 之类型转换 Converter 1.1 目录 1.1 目录 1. ...
- ACM-ICPC 2017 Asia Urumqi:A. Coins(DP)
挺不错的概率DP,看似基础,实则很考验扎实的功底 这题很明显是个DP,为什么???找规律或者算组合数这种概率,N不可能给的这么友善... 因为DP一般都要在支持N^2操作嘛. 稍微理解一下,这DP[i ...
- required: true,el-upload :action="UploadUrl()"
<el-form-item label="所属班级:" prop="Name" :rules="[{ required: true, messa ...
- PairWork-电梯调度程序结对编程【附加题】
1 接口改进 1) 之前判断电梯是否闲置的函数不太好理解,重新修改了,如下所示: //是否停顿状态(停止的以及开门间隔>=0) public bool IsIdle { get { return ...
- 1.个人项目 Individual Project
https://github.com/sunlitao 一. 实验1通讯录管理系统 通讯录中的联系人包含以下信息项:姓名.手机.办公电话.家庭电话.电子邮箱.所在省市.工作单位.家庭住址,群组分类(亲 ...
- github作业
链接: https://github.com/liuyu13/liuyu13-1 总结:git可以学习的东西还有很多.git协议,分布式协作,git项目管理,git技巧,github的使用和实践, ...