[洛谷P2154] SDOI2009 虔诚的墓主人
问题描述
小W是一片新造公墓的管理人。公墓可以看成一块N×M的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地。
当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地。为了体现自己对主的真诚,他们希望自己的墓地拥有着较高的虔诚度。
一块墓地的虔诚度是指以这块墓地为中心的十字架的数目。一个十字架可以看成中间是墓地,墓地的正上、正下、正左、正右都有恰好k棵常青树。
小W希望知道他所管理的这片公墓中所有墓地的虔诚度总和是多少。
输入格式
输入文件religious.in的第一行包含两个用空格分隔的正整数N和M,表示公墓的宽和长,因此这个矩形公墓共有(N+1) ×(M+1)个格点,左下角的坐标为(0, 0),右上角的坐标为(N, M)。
第二行包含一个正整数W,表示公墓中常青树的个数。
第三行起共W行,每行包含两个用空格分隔的非负整数xi和yi,表示一棵常青树的坐标。输入保证没有两棵常青树拥有相同的坐标。
最后一行包含一个正整数k,意义如题目所示。
输出格式
输出文件religious.out仅包含一个非负整数,表示这片公墓中所有墓地的虔诚度总和。为了方便起见,答案对2,147,483,648取模。
样例输入
5 6
13
0 2
0 3
1 2
1 3
2 0
2 1
2 4
2 5
2 6
3 2
3 3
4 3
5 2
2
样例输出
6
说明
图中,以墓地(2, 2)和(2, 3)为中心的十字架各有3个,即它们的虔诚度均为3。其他墓
地的虔诚度为0。

对于30%的数据,满足1 ≤ N, M ≤ 1,000。
对于60%的数据,满足1 ≤ N, M ≤ 1,000,000。
对于100%的数据,满足1 ≤ N, M ≤ 1,000,000,000,0 ≤ xi ≤ N,0 ≤ yi ≤ M,1 ≤ W ≤ 100,000,1 ≤ k ≤ 10。
存在50%的数据,满足1 ≤ k ≤ 2。
存在25%的数据,满足1 ≤ W ≤ 10000。
解析
设点A上面有a棵树,下面有b棵树,左边有c棵树,右边有d棵树。那么,点A的虔诚度为
\]
在纵坐标相同的两棵树之间,所有墓地的左右数量不变,因此这些墓地的虔诚度之和就是左右的组合数的乘积再乘上每一列的组合数乘积之和。我们有如下做法:将每棵树按照纵坐标从小到大排序,纵坐标相同按横坐标从小到大排序。用树状数组维护每一列上的组合数乘积,即\(C_a^k+C_b^k\)。每次扫描一行,在两个相邻的树之间统计答案,用区间求和即可实现。每扫描一行后更新树状数组中的值。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long
#define N 2000002
using namespace std;
const int mod=2147483648;
struct node{
int x,y;
}a[N];
int n,m,w,t,i,j,k,vx[N],vy[N],c[N],sum[N],num[N],f[N][12],n1,n2;
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
int my_comp(const node &a,const node &b)
{
if(a.y==b.y) return a.x<b.x;
return a.y<b.y;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y)
{
for(int i=x;i<=n1;i+=lowbit(i)) c[i]=(c[i]+y+mod)%mod;
}
int ask(int x)
{
int ans=0;
for(int i=x;i>=1;i-=lowbit(i)) ans=(ans+c[i]+mod)%mod;
return ans;
}
signed main()
{
n=read();m=read();w=read();
for(i=1;i<=w;i++){
a[i].x=read(),a[i].y=read();
vx[i]=a[i].x;
vy[i]=a[i].y;
}
t=read();
f[0][0]=1;
for(i=1;i<=w;i++){
f[i][0]=1;
for(j=1;j<=t;j++) f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
}
sort(vx+1,vx+w+1);
sort(vy+1,vy+w+1);
sort(a+1,a+w+1,my_comp);
n1=unique(vx+1,vx+w+1)-vx-1;
n2=unique(vy+1,vy+w+1)-vy-1;
for(i=1;i<=w;i++){
a[i].x=lower_bound(vx+1,vx+n1+1,a[i].x)-vx;
a[i].y=lower_bound(vy+1,vy+n2+1,a[i].y)-vy;
sum[a[i].x]++;
}
i=j=1;
int ans=0;
while(i<=w){
while(a[i].y==a[j].y) j++;
int cnt=j-i,now=1;
for(k=i+1;k<j;k++,now++){
int l=a[k-1].x,r=a[k].x;
ans=(ans+(ask(r-1)-ask(l)+mod)%mod*f[now][t]%mod*f[cnt-now][t]%mod)%mod;
}
for(k=i;k<j;k++){
int p=a[k].x;
add(p,-f[num[p]][t]*f[sum[p]-num[p]][t]%mod);
num[p]++;
add(p,f[num[p]][t]*f[sum[p]-num[p]][t]%mod);
}
i=j;
}
printf("%lld\n",(ans%mod+mod)%mod);
return 0;
}
[洛谷P2154] SDOI2009 虔诚的墓主人的更多相关文章
- BZOJ1227或洛谷2154 [SDOI2009]虔诚的墓主人
BZOJ原题链接 洛谷原题链接 又是扫描线,题解可看大佬的博客(太懒了不想打) #include<cstdio> #include<algorithm> using names ...
- bzoj1227 P2154 [SDOI2009]虔诚的墓主人
P2154 [SDOI2009]虔诚的墓主人 组合数学+离散化+树状数组 先看题,结合样例分析,易得每个墓地的虔诚度=C(正左几棵,k)*C(正右几棵,k)*C(正上几棵,k)*C(正下几棵,k),如 ...
- P2154 [SDOI2009]虔诚的墓主人 树状数组
https://www.luogu.org/problemnew/show/P2154 题意 在一个坐标系中,有w(1e5)个点,这个图中空点的权值是正上,正下,正左,正右各取k个的排列组合情况.计算 ...
- P2154 [SDOI2009]虔诚的墓主人
略有一点点思维的题. 首先,如果一个点上,下,左,右分别有\(a,b,c,d\)棵树,那这个点的十字架方案为\(C_{a}^{k}C_{b}^{k}C_{c}^{k}C_{d}^{k}\). 按x坐标 ...
- luogu P2154 [SDOI2009]虔诚的墓主人
luogu 下面记一个点上下左右点数分别为\(u_i,d_i,l_i,r_i\) 枚举每个中间点太慢了,考虑枚举两个点之间横的一条线段,这里面的点左边点数目都相同,右边点数目都相同,然后只要查一下区间 ...
- 【BZOJ1227】[SDOI2009]虔诚的墓主人(线段树)
[BZOJ1227][SDOI2009]虔诚的墓主人(线段树) 题面 BZOJ 洛谷 题解 显然发现答案就是对于每一个空位置,考虑上下左右各有多少棵树,然后就是这四个方向上树的数量中选\(K\)棵出来 ...
- 【LG2154】[SDOI2009]虔诚的墓主人
[LG2154][SDOI2009]虔诚的墓主人 题面 洛谷 题解 如果您没有看懂题,请反复阅读题面及样例 可以发现,对于某一个点,它的答案就是上下左右几个组合数乘起来. 这样直接做复杂度显然爆炸,考 ...
- BZOJ 1227: [SDOI2009]虔诚的墓主人
1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec Memory Limit: 259 MBSubmit: 1078 Solved: 510[Submit][Stat ...
- Bzoj 1227: [SDOI2009]虔诚的墓主人 树状数组,离散化,组合数学
1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec Memory Limit: 259 MBSubmit: 895 Solved: 422[Submit][Statu ...
随机推荐
- Eclipse与Tomcat
新进一个Web项目,有些小坎坷,于是引发了对于Eclipse和Tomcat的配置关系的思考. 首先提及一点当年的观点:Tomcat是一个容器,所有的功能都是以插件的形式放入其中:比如tomcat就是o ...
- 《React+Redux前端开发实战》笔记1:不涉及React项目构建的Hello World案例
本小节实现一个不涉及项目构建的Hello World. [React的第一个Hello World网页] 源码地址:https://jsfiddle.net/allan91/2h1sf0ky/8/ & ...
- for循环、列表的切片、元组
一.遍历整个列表 使用for语句循环将列表每取出一个变量,然后存储在中间变量中,打印中间变量:循环取出: 1.简单for循环 示例: carssa = ['richan','fengtian','be ...
- eclipse 或 STS 卸载SVN 插件
help菜单 ==> about eclipse ==>install details按钮 ==> installed software选项卡 选中下面的这几项,点击 uni ...
- BeautifulSoup库的基本元素
BeautifulSoup库 <html> <body> <p class='title'></p> </body> </html&g ...
- C++自学教程第一课——你好世界,我是柠檬鲸。
C++系列教程现在在自己学校的一个博客平台发布,几个朋友一起搭建的 [C++基础教程系列](https://blog.ytmaxoj.org/cpp_basic_liuary-0/) 下面是原来的正文 ...
- spring mvc + xmlHttpRequest2.0 实现无刷新上传文件,带进度条和剩余时间
1.springmvc支持文件上传,需要在spring-mvc.xml配置文件中加上下面的一段话: <!-- 支持上传文件 --> <bean id="multipartR ...
- [多校联考2019(Round 5 T2)]蓝精灵的请求(二分图染色+背包)
[多校联考2019(Round 5)]蓝精灵的请求(二分图染色+背包) 题面 在山的那边海的那边住着 n 个蓝精灵,这 n 个蓝精灵之间有 m 对好友关系,现在蓝精灵们想要玩一个团队竞技游戏,需要分为 ...
- 模板 - SG函数
https://scut.online/p/93 每次取走的石子是b的幂次.打表暴力发现规律. #include <bits/stdc++.h> using namespace std; ...
- MVCC/分布式事务简介
之前我们学习了RocksDB,但这还只是一个最基础的存储引擎.如果想把它在生产环境中用起来,还需要解决很多问题: 如何从单机扩展到分布式? 如何实现事务,并对事务进行并发控制? 用户接口能不能高级一点 ...