题目大意

  公墓可以看成一块N×M的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地。一块墓地的虔诚度是指以这块墓地为中心的十字架的数目,一个十字架可以看成中间是墓地,墓地的正上、正下、正左、正右都有恰好k棵常青树。小W希望知道他所管理的这片公墓中所有墓地的虔诚度总和是多少。1 ≤ N, M ≤ 1,000,000,000,0 ≤ xi ≤ N,0 ≤ yi ≤ M,1 ≤ W ≤ 100,000,1 ≤ k ≤ 10。

题解

  首先,由N、M的巨大数量和相对地W的较小数量让我们想到离散化。一个点若其所在排和列都没有常青树,则这些点都是无效的。所以我们可以通过离散化将原矩形中的无效部分删去得到一个小矩形。

  然而离散化后我们不可以枚举坐标,这样时间复杂度至少是O(W^2)。所以我们就要以两个点之间的间隔上做文章。

  对于一个点$i$,定义它们上下左右方的常青树(包括它自己)个数分别为$u_i,b_i,l_i,r_i$,它对答案的贡献为$C_{u_i}^k C_{b_i}^k C_{l_i}^k C_{r_i}^k$。对于一排上相邻的两个点$a,b$,它们之间的间隔上每一个点的$C_{l_i}^k C_{r_i}^k$都相等,它们对答案的贡献是$C_{l_a}^k C_{r_a}^k \sum_{i在a,b之间}C_{u_i}^k C_{b_i}^k$。看见sigma了,是不是可以想到树状数组?当处理当前排时,树状数组的key值为列数(也就是架在这一行上),维护的是该行上每一个点的$C_{u_i}^k C_{b_i}^k$的前缀和。这样一行一行地按照列数从小到大(排一下序)扫描常青树,边查询边修改树状数组,这道题就完成了。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX_NODE = 100010, MAX_CANDIDATE_VAL = MAX_NODE * 2, MAX_K = 15;
const unsigned int P = 2147483648u;
int TotRow, TotCol, TotNode, K;
int RowNodeCnt[MAX_CANDIDATE_VAL], ColNodeCnt[MAX_CANDIDATE_VAL];
unsigned int C[MAX_NODE][MAX_K]; struct Discretion
{
private:
int OrgData[MAX_CANDIDATE_VAL], Rank[MAX_CANDIDATE_VAL];
int N; int LowerBound(int l, int r, int k)
{
while (l < r)
{
int mid = (l + r) / 2;
if (k <= OrgData[mid])
r = mid;
else
l = mid + 1;
}
return l;
} public:
Discretion(int n, int *orgData)
{
N = n;
for (int i = 1; i <= N; i++)
OrgData[i] = orgData[i];
sort(OrgData + 1, OrgData + N + 1);
OrgData[0] = -1;
int curRank = 0;
for (int i = 1; i <= N; i++)
Rank[i] = OrgData[i] == OrgData[i - 1] ? curRank : ++curRank;
} int GetRank(int val)
{
return Rank[LowerBound(1, N, val)];
} int GetMaxRank()
{
return Rank[N];
}
}; struct Node
{
int Row, Col; bool operator < (const Node& a) const
{
return Row != a.Row ? Row < a.Row : Col < a.Col;
}
}_nodes[MAX_NODE]; struct BIT
{
private:
unsigned int C[MAX_CANDIDATE_VAL];
int N; int Lowbit(int x)
{
return x & -x;
} public:
BIT(int n):N(n){} void Update(int p, unsigned int delta, bool add)
{
while (p <= N)
{
add ? C[p] += delta : C[p] -= delta;
p += Lowbit(p);
}
} unsigned int Query(int p)
{
unsigned int ans = 0;
while (p >= 1)
{
ans += C[p];
p -= Lowbit(p);
}
return ans;
}
}; void Read()
{
scanf("%d%d%d", &TotRow, &TotCol, &TotNode);
for (int i = 1; i <= TotNode; i++)
scanf("%d%d", &_nodes[i].Row, &_nodes[i].Col);
scanf("%d", &K);
} void GetC()
{
for (int i = 0; i <= TotNode; i++)
{
C[i][0] = 1;
if (i <= K)
C[i][i] = 1;
for (int j = 1; j <= min(i - 1, K); j++)
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
} void Discrete()
{
static int a[MAX_CANDIDATE_VAL];
for (int i = 1; i <= TotNode; i++)
{
a[i * 2 - 1] = _nodes[i].Row;
a[i * 2] = _nodes[i].Col;
}
static Discretion g(TotNode * 2, a);
TotRow = TotCol = g.GetMaxRank();
for (int i = 1; i <= TotNode; i++)
{
_nodes[i].Row = g.GetRank(_nodes[i].Row);
_nodes[i].Col = g.GetRank(_nodes[i].Col);
RowNodeCnt[_nodes[i].Row]++;
ColNodeCnt[_nodes[i].Col]++;
}
} int GetAns()
{
static BIT g(TotCol);
unsigned int ans = 0;
sort(_nodes + 1, _nodes + TotNode + 1);
int pass = 0;//passNodeCntInCurRow
static int colPassCnt[MAX_CANDIDATE_VAL];
for (int i = 1; i < TotNode; i++)
{
pass = _nodes[i - 1].Row == _nodes[i].Row ? pass + 1 : 1;
if (_nodes[i + 1].Row == _nodes[i].Row)
ans += C[pass][K] * C[RowNodeCnt[_nodes[i].Row] - pass][K] * (g.Query(_nodes[i + 1].Col - 1) - g.Query(_nodes[i].Col));
g.Update(_nodes[i].Col, g.Query(_nodes[i].Col) - g.Query(_nodes[i].Col - 1), false);
colPassCnt[_nodes[i].Col]++;
g.Update(_nodes[i].Col, C[colPassCnt[_nodes[i].Col]][K] * C[ColNodeCnt[_nodes[i].Col] - colPassCnt[_nodes[i].Col]][K], true);
}
return (int)(ans % P);
} int main()
{
Read();
GetC();
Discrete();
printf("%d\n", GetAns());
return 0;
}

  

luogu2154 [SDOI2009] 虔诚的墓主人 离散化 树状数组 扫描线的更多相关文章

  1. [BZOJ1227][SDOI2009]虔诚的墓主人 组合数+树状数组

    1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec  Memory Limit: 259 MBSubmit: 1433  Solved: 672[Submit][Stat ...

  2. BZOJ1227 SDOI2009 虔诚的墓主人【树状数组+组合数】【好题】*

    BZOJ1227 SDOI2009 虔诚的墓主人 Description 小W 是一片新造公墓的管理人.公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地. ...

  3. BZOJ1227 [SDOI2009]虔诚的墓主人 【树状数组】

    题目 小W 是一片新造公墓的管理人.公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地.为 ...

  4. BZOJ 1227 虔诚的墓主人(离散化+树状数组)

    题目中矩形的尺寸太大,导致墓地的数目太多,如果我们统计每一个墓地的虔诚度,超时是一定的. 而常青树的数目<=1e5.这启发我们从树的方向去思考. 考虑一行没有树的情况,显然这一行的墓地的虔诚度之 ...

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

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

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

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

  7. CodeForces 540E - Infinite Inversions(离散化+树状数组)

    花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...

  8. Ultra-QuickSort(归并排序+离散化树状数组)

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 50517   Accepted: 18534 ...

  9. HDU 5862 Counting Intersections(离散化+树状数组)

    HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...

随机推荐

  1. 软件架构自学笔记----分享“去哪儿 Hadoop 集群 Federation 数据拷贝优化”

    去哪儿 Hadoop 集群 Federation 数据拷贝优化 背景 去哪儿 Hadoop 集群随着去哪儿网的发展一直在优化改进,基本保证了业务数据存储量和计算量爆发式增长下的存储服务质量.然而,随着 ...

  2. IC验证概念总结

    一份代码,在写完之后,一定要再经过一次或多次整理和打磨,才能算完成的:一份代码,一定要把其有效代码行,精简.锤炼到最少.最短.最有效,才能算完成的.   下面这些问题和回答是忘记是在哪里看到的了,参考 ...

  3. Mac OS 小知识

         删除Mac OS输入法中自动记忆的用户词组 有时候不小心制造了一个错误的词组,结果也被输入法牢牢记住,这时候可以用shift+delete组合键来删除      快捷键拾遗 Fn+Delet ...

  4. Python之模块、正则

    一.模块import 模块的实质就是把要导入模块里面的代码,从上到下执行一遍,找模块的顺序是,先从当前目录下找,找不到的话,再环境变量里面找导入的模块名字最好不要有.,a.import sysprin ...

  5. mysql 如何用命令清除表数据,让表数据索引是从0开始呢?

    truncate MYTABLE 这样就可以了 其实这个命令就相当于删除表再建 所有的数据都还原 可以使用工具来完成这个操作 右键单击要操作的表,选择Turncale Table 执行查询语句,数据就 ...

  6. Linux学习笔记之 Btrfs文件系统简介及使用

    Btrfs 也有一个重要的缺点,当 BTree 中某个节点出现错误时,文件系统将失去该节点之下的所有的文件信息.而 ext2/3 却避免了这种被称为”错误扩散”的问题. Btrfs相关介绍: Btrf ...

  7. 【python】详解numpy库与pandas库axis=0,axis= 1轴的用法

    对数据进行操作时,经常需要在横轴方向或者数轴方向对数据进行操作,这时需要设定参数axis的值: axis = 0 代表对横轴操作,也就是第0轴: axis = 1 代表对纵轴操作,也就是第1轴: nu ...

  8. Kail更新源、输入法、浏览器

    更新源 kali官方的更新源:图中的kali-rolling是kali目前最新的代号,kali有两个代号(codename):sana和kali-rolling: 查看自己的kali linux源版本 ...

  9. 【Codeforces 4D】Mysterious Present

    [链接] 我是链接,点我呀:) [题意] 要求长度和宽度都严格递增(选择一个序列) 然后你一开始有一个长度和宽度 要求这个一开始所给的长度和宽度能接在你选择的一段连续的长度宽度的开头 (且保持原来的性 ...

  10. 洛谷 1373 dp 小a和uim之大逃离 良心题解

    洛谷 1373 dp 这题还不算太难,,当初看的时候不是很理解题意,以为他们会选择两条不同的路径,导致整体思路混乱 传送门 其实理解题意和思路之后还是敲了不短的时间,一部分身体原因再加上中午休息不太好 ...