题目

小W 是一片新造公墓的管理人。公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地。当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地。为了体现自己对主的真诚,他们希望自己的墓地拥有着较高的虔诚度。一块墓地的虔诚度是指以这块墓地为中心的十字架的数目。一个十字架可以看成中间是墓地,墓地的正上、正下、正左、正右都有恰好k 棵常青树。小W 希望知道他所管理的这片公墓中所有墓地的虔诚度总和是多少

输入格式

第一行包含两个用空格分隔的正整数N 和M,表示公墓的宽和长,因此这个矩形公墓共有(N+1) ×(M+1)个格点,左下角的坐标为(0, 0),右上角的坐标为(N, M)。第二行包含一个正整数W,表示公墓中常青树的个数。第三行起共W 行,每行包含两个用空格分隔的非负整数xi和yi,表示一棵常青树的坐标。输入保证没有两棵常青树拥有相同的坐标。最后一行包含一个正整数k,意义如题目所示。

输出格式

包含一个非负整数,表示这片公墓中所有墓地的虔诚度总和。为了方便起见,答案对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。

所有数据满足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。

注意:”恰好有k颗树“,这里的恰好不是有且只有,而是从>=k的树中恰好选k棵

题解

题目中的模数等于\(2^31\),所以int自然溢出就相当于取模
我们记一个点上下左右的树数量为u、d、l、r,则每个点的贡献是\(C_{u}^{k} * C_{d}^{k} * C_{l}^{k} * C_{r}^{k}\)
点的范围很大,我们将其离散化到100000以内
但总共\(W^2\)个点,不能直接算,但树只有\(W\)个,考虑从树出发
我们将所有树排序后,对于横坐标相同的两棵树之间的点,其式子中的\(C_{u}^{k} * C_{d}^{k}\)是一样的
我们用树状数组维护\(C_{l}^{k} * C_{r}^{k}\),就可以加速运算了

#include<iostream>
#include<cstdio>
#include<algorithm>
#define lbt(x) (x & -x)
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
inline int read(){int out = 0,flag = 1; char c = getchar();while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}return out * flag;
}
int s[maxn],C[maxn][11],b[maxn],tot,n,k;
int U[maxn],D[maxn],L[maxn],R[maxn],V[maxn];
struct point{int x,y;}p[maxn];
int getn(int x){return lower_bound(b + 1,b + 1 + tot,x) - b;}
inline bool operator <(const point& a,const point& b){return a.x == b.x ? a.y < b.y : a.x < b.x;
}
void add(int u,int v){while (u <= tot) s[u] += v,u += lbt(u);}
void mus(int u,int v){while (u <= tot) s[u] -= v,u += lbt(u);}
int query(int u){int ans = 0; while (u) ans += s[u],u -= lbt(u); return ans;}
int sum(int l,int r){return query(r) - query(l - 1);}
void cal(){for (int i = 0; i <= n; i++){C[i][0] = C[i][i] = 1;for (int j = 1; j <= i && j <= 10; j++)C[i][j] = C[i - 1][j] + C[i - 1][j - 1];}
}
void init(){read(); read();n = read();cal();for (int i = 1; i <= n; i++)b[i] = p[i].x = read(),p[i].y = read();sort(b + 1,b + 1 + n); tot = 1;for (int i = 2; i <= n; i++) if (b[i] != b[tot]) b[++tot] = b[i];for (int i = 1; i <= n; i++) p[i].x = getn(p[i].x);for (int i = 1; i <= n; i++) b[i] = p[i].y;sort(b + 1,b + 1 + n); tot = 1;for (int i = 2; i <= n; i++) if (b[i] != b[tot]) b[++tot] = b[i];for (int i = 1; i <= n; i++) p[i].y = getn(p[i].y);k = read();
}
void solve(){sort(p + 1,p + 1 + n);int ans = 0;for (int i = 1; i <= n; i++) U[p[i].x]++,R[p[i].y]++;for (int i = 1; i <= n; i++){if (i > 1 && p[i - 1].x == p[i].x && p[i - 1].y + 1 < p[i].y)ans += C[U[p[i].x]][k] * C[D[p[i].x]][k] * sum(p[i - 1].y + 1,p[i].y - 1);U[p[i].x]--; D[p[i].x]++;R[p[i].y]--; L[p[i].y]++;add(p[i].y,-V[p[i].y]);add(p[i].y,V[p[i].y] = C[L[p[i].y]][k] * C[R[p[i].y]][k]);}cout << (ans >= 0 ? ans : ans + 2147483647 + 1) << endl;
}
int main(){init();solve();return 0;
}

转载于:https://www.cnblogs.com/Mychael/p/8478222.html

BZOJ1227 [SDOI2009]虔诚的墓主人 【树状数组】相关推荐

  1. bzoj1227: [SDOI2009]虔诚的墓主人(树状数组,组合数)

    传送门 首先,对于每一块墓地,如果上下左右各有$a,b,c,d$棵树,那么总的虔诚度就是$C_k^a*C_k^b*C_k^c*C_k^d$ 那么我们先把所有的点都给离散,然后按$x$为第一关键字,$y ...

  2. P1972 [SDOI2009]HH的项链(离线树状数组)

    整理的算法模板合集: ACM模板 #include<cstdio> #include<algorithm> #include<cstring> #include&l ...

  3. 【树状数组】Bzoj1878[SDOI2009] HH的项链

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变 ...

  4. bzoj 1878: [SDOI2009]HH的项链 ——树状数组+ 差分

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一 段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此他的项链变得 ...

  5. 1227: [SDOI2009]虔诚的墓主人

    1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec  Memory Limit: 259 MB Submit: 1083  Solved: 514 [Submit][St ...

  6. 数据结构一【树状数组】普通、二维、离线树状数组的(单点修改,单点查询,区间修改,区间查询)模板及应用例题总结

    文章目录 树状数组 lowbit 线段树与树状数组 单点修改 区间查询 区间修改 区间求和 二维树状数组 离线树状数组 例题 POJ:stars MooFest [SDOI2009]HH的项链 Tur ...

  7. [HEOI2012]采花(思维 + 离线 + 树状数组)

    题目链接 分析 我只能说太妙了- 离线 + 树状数组 参考题解: 这个题要和<HH的项链>做对比: 关键就是为什么要离线处理,以及 怎么对区间进行排序和维护: [SDOI2009]HH的项 ...

  8. 树状数组(未填完的坑)

    Flag:八月底开学前写完!!! 介绍 树状数组(Binary Indexed Tree)其实是一种简单的数据结构,因为简单易懂经常代替线段树来求数列的前缀和.区间和等 原理 很久很久以前,有一个聪明 ...

  9. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

最新文章

  1. R语言基本操作函数(1)变量的基本操作
  2. java一维数组插入元素_Java 数组 之 一维数组 追加 元素
  3. [导入]Google Earth坐标集(能更看清这个世界喽!)
  4. 三网融合试点,是一个商机还是烫山芋?
  5. scrapy爬取汽车之家宝马5系图片
  6. 反射工厂在数据访问层的应用
  7. JZ6-旋转数组的最小数字
  8. 设置全屏代码android,Android实现全屏显示的方法
  9. Java测试用例简介
  10. 《概率论与数理统计》(浙大第四版)第一章总结笔记(纯手写)
  11. 测试分析——熟悉被测软件
  12. SSL证书是要怎么部署的,SSL证书怎么安装你知道吗?
  13. 音视频处理基础知识扫盲:数字视频YUV像素表示法以及视频帧和编解码概念介绍
  14. DC基础学习(二)Synthesis Flow1
  15. Surround360 README文档——中文翻译
  16. 计算机教学设计与反思,[信客教案及反思] 信息技术教案课后反思
  17. 公司该如何创建适合自己的区块链产品、联盟链、私链
  18. js将图片转base64两种方法
  19. python 运算符的优先顺序
  20. 重庆市行政边界划分矢量图

热门文章

  1. poj 3258:River Hopscotch(二分)
  2. yum 安装php7和相关扩展
  3. 快速批量导入庞大数据到SQL SERVER数据库(ADO.NET)
  4. Redis常用命令集
  5. python处理时间加减
  6. Active Diretory 全攻略(三)--建立域(2)
  7. Top-push Video-based Person Re-identification
  8. 机器学习知识点(三十六)分类器性能度量指标f1-score
  9. (转载)简单linux C++内存池
  10. 线程与内核对象的同步——Windows核心编程学习手札之九