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}\times \sum_{y1<l<y2}C_{l\_LEFT}^{k}\times C_{l\_RIGHT}^{k}
\]

你们意会一下。

观察这个式子,\(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 虔诚的墓主人的更多相关文章

  1. 「题解报告」 P3167 [CQOI2014]通配符匹配

    「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...

  2. 「题解报告」P4577 [FJOI2018]领导集团问题

    题解 P4577 [FJOI2018]领导集团问题 题解区好像没有线段树上又套了二分的做法,于是就有了这片题解. 题目传送门 怀着必 WA 的决心交了两发,一不小心就过了. 题意 求一个树上最长不下降 ...

  3. 「题解报告」SP16185 Mining your own business

    题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...

  4. 「题解报告」Blocks

    P3503 Blocks 题解 原题传送门 思路 首先我们可以发现,若 \(a_l\) ~ \(a_r\) 的平均值大于等于 \(k\) ,则这个区间一定可以转化为都大于等于 \(k\) 的.我们就把 ...

  5. 「题解报告」P3354

    P3354 题解 题目传送门 一道很恶心的树形dp 但是我喜欢 题目大意: 一片海旁边有一条树状的河,入海口有一个大伐木场,每条河的分叉处都有村庄.建了伐木场的村庄可以直接处理木料,否则要往下游的伐木 ...

  6. 「题解报告」CF1067A Array Without Local Maximums

    大佬们的题解都太深奥了,直接把转移方程放出来让其他大佬们感性理解,蒟蒻们很难理解,所以我就写了一篇让像我一样的蒟蒻能看懂的题解 原题传送门 动态规划三部曲:确定状态,转移方程,初始状态和答案. --神 ...

  7. 「题解报告」P7301 【[USACO21JAN] Spaced Out S】

    原题传送门 神奇的5分算法:直接输出样例. 20分算法 直接把每个点是否有牛的状态DFS一遍同时判断是否合法,时间复杂度约为\(O(2^{n^2})\)(因为有判断合法的剪枝所以会比这个低).而在前四 ...

  8. 【Luogu】P2154虔诚的墓主人(树状数组)

    题目链接 这题就是考虑我们有这样一个情况

  9. bzoj1227 P2154 [SDOI2009]虔诚的墓主人

    P2154 [SDOI2009]虔诚的墓主人 组合数学+离散化+树状数组 先看题,结合样例分析,易得每个墓地的虔诚度=C(正左几棵,k)*C(正右几棵,k)*C(正上几棵,k)*C(正下几棵,k),如 ...

随机推荐

  1. kafka消费

    消费模型 kafka模型使用了 发布/订阅.点对点模型. 消息发布 在producer端,通过分片策略,找到对应topic下面的Partition leader,把消息发送到当前Partition 消 ...

  2. 一篇文章带你深入浅出Vuex

    在写Vuex之前,我们先用一个简单的例子来实现一个小demo 大家都知道Vue的父传子用在很多场景,比如像这样: 父组件: <template> <div id="app& ...

  3. Redis基础与性能调优

    Redis是一个开源的,基于内存的结构化数据存储媒介,可以作为数据库.缓存服务或消息服务使用. Redis支持多种数据结构,包括字符串.哈希表.链表.集合.有序集合.位图.Hyperloglogs等. ...

  4. 前端下载图片的N种方法

    前几天一个简单的下载图片的需求折腾了我后端大佬好几天,最终还是需要前端来搞,开始说不行的笔者最后又行了,所以趁着这个机会来总结一下下载图片到底有多少种方法. 先起个服务 使用expressjs起个简单 ...

  5. VS Code 调教日记(2022.6.26更新)

    VS Code 调教日记(2022.6.26更新) 基于msys2的MinGW-w64 GCC的环境配置 下载并安装msys2 到路径...msys2安装路径...\msys64\etc\pacman ...

  6. Http实战之Wireshark抓包分析

    Http实战之Wireshark抓包分析 Http相关的文章网上一搜一大把,所以笔者这一系列的文章不会只陈述一些概念,更多的是通过实战(抓包+代码实现)的方式来跟大家讨论Http协议中的各种细节,帮助 ...

  7. win10设置Python程序定时运行(设置计划任务)

    今天来设置一下定时执行Pycharm内的脚本: 这个要基于win10 的任务计划程序(设置 > 控制面板 > 系统和安全 > 管理工具 > 任务计划程序) 1. create ...

  8. 没想到吧,Spring中还有一招集合注入的写法

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 哈喽大家好啊,我是Hydra. Spring作为项目中不可缺少的底层框架,提供的最基础的功能就是bean的管理了.bean的注入相信大家都比较熟 ...

  9. 官宣!微软发布 VS Code Server!

    北京时间 2022 年 7 月 7 日,微软在 VS Code 官方博客中宣布了 Visual Studio Code Server! 远程开发的过去与未来 2019 年,微软发布了 VS Code ...

  10. java -jar -Xbootclasspath/a:/xxx/config xxx .jar 和 java -jar xxx .jar 的区别

    1.如果有用Xbootclasspath的话则config的文件会直接覆盖jar里面的resouces文件,覆盖application.yml ,也会覆盖logback-spring.xml ,比如j ...