「题解报告」P2154 虔诚的墓主人
P2154 虔诚的墓主人 题解
题意
在 \(n\times m\) 一个方格上给你 \(w\) 个点,求方格里每个点正上下左右各选 \(k\) 个点的方案数。
\(1 \le N, M \le 1,000,000,000,0 \le x_i \le N,0 \le y_i \le M,1 \le W \le 100,000,1 \le k \le 10\)。
思路
首先看到 \(N,M\) 这么大,肯定要先离散化一下。
然后考虑怎么求方案数。
我们先对离散化后的点排个序,然后考虑两个 \(x\) 相同的点 \(x,y1\) 和 \(x,y2\) 之间的所有点的方案数。
显然是:
\]
你们意会一下。
观察这个式子,\(C_{y1\_UP}^{k}\times C_{y2\_DOWN}^{k}\) 当前已知,可以用前缀和维护 \(\sum C_{l\_LEFT}^{k}\times C_{l\_RIGHT}^{k}\)。
那么我们就开一个树状数组,维护前 \(i\) 行的 \(C_{l\_LEFT}^{k}\times C_{l\_RIGHT}^{k}\) 之和,每次碰到一个点 \(x,yy\) 时把当前行的影响清除,再令 \(yy\_LEFT+1,yy\_RIGHT-1\),再重新计入前缀和。
可以参考代码中 Solve 函数中变量 \(u\) 的求法。
时间复杂度 \(O(nlogn)\)。
我这个菜鸡居然因为取模取错了调了两节课。
Code
#include <bits/stdc++.h>
#define _for(i,a,b) for(ll i=a;i<=b;++i)
#define for_(i,a,b) for(ll i=a;i>=b;--i)
#define ll long long
using namespace std;
const ll N=1e5+10,P=2147483648;
ll n,m,w,k,q[N],h[N],z[N],y[N],ans;
struct tree{ll x,y;}t[N];
inline ll rnt(){
ll x=0,w=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*w;
}
namespace SZSZ{
/*树状数组*/
ll b[N];
inline ll lowbit(ll x){return x&-x;}
inline void UpDate(ll x,ll y){
while(x<=w){
b[x]=(b[x]+y)%P;
x+=lowbit(x);
}
return;
}
inline ll Query(ll x){
if(x==0)return 0;
ll sum=0;
while(x){
sum=(sum+b[x])%P;
x-=lowbit(x);
}
return sum;
}
}
namespace LISAN{
/*离散化*/
vector<ll>xx,yy;
inline bool cmp(tree a,tree b){
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
inline void Add(ll x,ll y){
xx.push_back(x);
yy.push_back(y);
return;
}
inline void LiSan(){
sort(xx.begin(),xx.end());
sort(yy.begin(),yy.end());
xx.erase(unique(xx.begin(),xx.end()),xx.end());
yy.erase(unique(yy.begin(),yy.end()),yy.end());
_for(i,1,w){
t[i].x=lower_bound(xx.begin(),xx.end(),t[i].x)-xx.begin()+1;
t[i].y=lower_bound(yy.begin(),yy.end(),t[i].y)-yy.begin()+1;
++h[t[i].x],++y[t[i].y];
}
sort(t+1,t+w+1,cmp);
return;
}
}
namespace SOLVE{
ll c[N*20][20]={0};
/*预处理组合数*/
inline void PreC(){
c[0][0]=1;
_for(i,1,w){
c[i][0]=1;
_for(j,1,min(k,i))
c[i][j]=(c[i-1][j]+c[i-1][j-1])%P;
}
}
/*求解*/
inline ll Solve(){
PreC();
_for(i,1,w-1){
++q[t[i].x];
++z[t[i].y];
if(t[i].x==t[i+1].x&&q[t[i].x]>=k&&h[t[i].x]-q[t[i].x]>=k){
ll up=c[q[t[i].x]][k];
ll dn=c[h[t[i].x]-q[t[i].x]][k];
ll ri=SZSZ::Query(t[i+1].y-1)-SZSZ::Query(t[i].y);
ans+=((up*dn+P)%P*ri+P)%P;
ans%=P;
}
ll u=((c[z[t[i].y]][k]*c[y[t[i].y]-z[t[i].y]][k]+P)%P-(SZSZ::Query(t[i].y)-SZSZ::Query(t[i].y-1)+P)%P+P)%P;
SZSZ::UpDate(t[i].y,u);
}
return ans;
}
}
int main(){
n=rnt(),m=rnt(),w=rnt();
_for(i,1,w){
t[i].x=rnt(),t[i].y=rnt();
LISAN::Add(t[i].x,t[i].y);
}
k=rnt();
LISAN::LiSan();
printf("%lld\n",SOLVE::Solve());
return 0;
}
/*
*/
「题解报告」P2154 虔诚的墓主人的更多相关文章
- 「题解报告」 P3167 [CQOI2014]通配符匹配
「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...
- 「题解报告」P4577 [FJOI2018]领导集团问题
题解 P4577 [FJOI2018]领导集团问题 题解区好像没有线段树上又套了二分的做法,于是就有了这片题解. 题目传送门 怀着必 WA 的决心交了两发,一不小心就过了. 题意 求一个树上最长不下降 ...
- 「题解报告」SP16185 Mining your own business
题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...
- 「题解报告」Blocks
P3503 Blocks 题解 原题传送门 思路 首先我们可以发现,若 \(a_l\) ~ \(a_r\) 的平均值大于等于 \(k\) ,则这个区间一定可以转化为都大于等于 \(k\) 的.我们就把 ...
- 「题解报告」P3354
P3354 题解 题目传送门 一道很恶心的树形dp 但是我喜欢 题目大意: 一片海旁边有一条树状的河,入海口有一个大伐木场,每条河的分叉处都有村庄.建了伐木场的村庄可以直接处理木料,否则要往下游的伐木 ...
- 「题解报告」CF1067A Array Without Local Maximums
大佬们的题解都太深奥了,直接把转移方程放出来让其他大佬们感性理解,蒟蒻们很难理解,所以我就写了一篇让像我一样的蒟蒻能看懂的题解 原题传送门 动态规划三部曲:确定状态,转移方程,初始状态和答案. --神 ...
- 「题解报告」P7301 【[USACO21JAN] Spaced Out S】
原题传送门 神奇的5分算法:直接输出样例. 20分算法 直接把每个点是否有牛的状态DFS一遍同时判断是否合法,时间复杂度约为\(O(2^{n^2})\)(因为有判断合法的剪枝所以会比这个低).而在前四 ...
- 【Luogu】P2154虔诚的墓主人(树状数组)
题目链接 这题就是考虑我们有这样一个情况
- bzoj1227 P2154 [SDOI2009]虔诚的墓主人
P2154 [SDOI2009]虔诚的墓主人 组合数学+离散化+树状数组 先看题,结合样例分析,易得每个墓地的虔诚度=C(正左几棵,k)*C(正右几棵,k)*C(正上几棵,k)*C(正下几棵,k),如 ...
随机推荐
- CVPR2022 | A ConvNet for the 2020s & 如何设计神经网络总结
前言 本文深入探讨了如何设计神经网络.如何使得训练神经网络具有更加优异的效果,以及思考网络设计的物理意义. 欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结.最新技术跟踪.经典论文解读.CV招聘 ...
- 记安装AWVS14过程踩的坑
由于之前的AWVS14用着用着无法扫描了,一扫就是失败,一气之下就重装系统了.重装系统后发现安装还是不行,折腾了好久,终于找到方法了. 安装acunetix_14.1.210324124.exe 没啥 ...
- python 基础知识-day10(面向对象)
1.面向对象的概念 拥有共同属性的一类进行归类的过程叫做面向对象. 2.注意事项 class定义类的时候,类名的首字母必须大写 3.面向对象案例 1 class Person(object): 2 d ...
- 安装ImageMagick7.1库以及php的Imagick扩展
由于ImageMagick7以下不支持heic等图片格式,所以重新安装了ImageMagick7.1版本支持heic格式,并写此文章记录一下. 如果安装过程中遇到一些未知的错误,https://ima ...
- Feign通过自定义注解实现路径的转义
本文主要讲解如果通过注解实现对路由中的路径进行自定义编码 背景 近期由于项目中需要,所以需要通过Feign封装一个对Harbor操作的sdk信息. 在调用的过程中发现,当请求参数中带有"/& ...
- java常见的面试题(一)
1.Collection 和 Collections 有什么区别? Collection 是一个集合接口(集合类的一个顶级接口).它提供了对集合对象进行基本操作的通用接口方法.Collection接口 ...
- Python程序入口 __name__ == ‘__main__‘ 有重要功能(多线程)而非编程习惯
文章来源于互联网(https://jq.qq.com/?_wv=1027&k=rX9CWKg4) 在Python中,被称为「程序的入口」的 if name =='main': 总是出现在各种示 ...
- 详解HashMap源码解析(上)
jdk版本:1.8 数据结构: HashMap的底层主要基于数组+链表/红黑树实现,数组优点就是查询块,HashMap通过计算hash码获取到数组的下标来查询数据.同样也可以通过hash码得到数组下标 ...
- Tapdata PDK 生态共建计划启动!Doris、OceanBase、PolarDB、SequoiaDB 等十余家厂商首批加入
2022年4月7日,Tapdata 正式启动 PDK 插件生态共建计划,致力于全面连接数据孤岛,加速构建更加开放的数据生态,以期让各行各业的使用者都能释放数据的价值,随时获取新鲜的数据.截至目前, ...
- 简单状压dp的思考 - 最大独立集问题和最大团问题 - 贰
接着上文 题目链接:最大独立集问题 上次说到,一种用状压DP解决任意无向图最大团问题(MCP)的方程是: 注:此处popcountmax代表按照二进制位下1的个数作为关键字比较,即选择二进制位下1的个 ...