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有关 ...
随机推荐
- 《Head First 设计模式》例子的C++实现(1 策略模式)
最近在学习设计模式,用的是 <Head First 设计模式>这本书.感觉这本书写的还是很不错的,深入浅出的介绍了各种常用的设计模式.唯一有点不方便的地方是这本书的例子全都是用的 Java ...
- ML.NET 示例:二元分类之信用卡欺诈检测
写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...
- 线程池ThreadPoolExecutor整理
项目用到线程池,但是其实很多人对原理并不熟悉 ,这里只是整理一下 ThreadPoolExecutor java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心 ...
- 用JS制作一个信息管理平台(1)
首先,介绍一些需要用到的基本知识. [JSON] JSON是数据交互中,最常用的一种数据格式. 由于各种语言的语法都不相同,在传递数据时,可以将自己语言中的数组.对象等转换为JSON字符串. 传递之后 ...
- 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--请求处理结果适配篇(7/8)
文章目录 前情概要 前面一大坨一大坨的代码把route.controller.action.attribute都搞完事儿了,最后剩下一部分功能就是串起来的调用. 那接下就说个说第二个中间件,也是最后一 ...
- ssh实现办公室电脑连接家中的电脑
友情提示:如果您不知道您家路由器管理页面的密码,请您忽略此文. 问题背景: 家中有台笔记本电脑,它是通过家中的路由器与外界联网的,这时,我想通过ssh服务让公司的电脑能连上我家中的笔记本. 可以画个图 ...
- Jenkins日常运维笔记-重启数据覆盖问题、迁移、基于java代码发版(maven构建)
之前在公司机房部署了一套jenkins环境,现需要迁移至IDC机房服务器上,迁移过程中记录了一些细节:1)jenkins默认的主目录放在当前用户家目录路径下的.jenkins目录中.如jenkins使 ...
- ELK实时日志分析平台环境部署--完整记录
在日常运维工作中,对于系统和业务日志的处理尤为重要.今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为例说明,如有误述,敬请指出)~ ==== ...
- Redis常见问题和解决办法梳理
=============Redis主从复制问题和解决办法 ================= 一.Redis主从复制读写分离问题 1)数据复制的延迟读写分离时,master会异步的将数据复制到sla ...
- 个人作业-Week1(新增详细说明)
快速看完整部教材,列出你仍然不懂的5到10个问题,发布在你的个人博客上. 如何提出有价值的问题? 请看这个文章:http://www.cnblogs.com/rocedu/p/5167941.html ...