题解:hzw大神的博客说的很清楚嘛

http://hzwer.com/1941.html

朴素的做法就是每个点如果它不是墓地那么就可形成十字架的数量就是这个c(点左边的树的数量,k)*c(点右边的树的数量,k)*c(点上边的树的数量,k)*c(点下边的树的数量,k)。这样的话要枚举每个点,复杂度很明显爆表。

再仔细分析一下,其实完全可以不用枚举每个点,只需要枚举那些树的位置就可以,(下面的点指的都是树而非点??蒟蒻语言不好)在同一列的两棵相邻的树之间的点的c(点左边的树的数量,k)*c(点右边的树的数量,k)是一样的,但是还是需要Σc(点上边的树的数量,k)*c(点下边的树的数量,k)(乘法分配率,自己yy一下),朴素枚举这些还是要复杂度爆表,于是问题就是如果在logn时间内搞定这个东西,于是想到如果维护“Σc(点上边的树的数量,k)*c(点下边的树的数量,k)”的信息(询问区间和,想到树状数组或者线段树),(有点类似于那个悬梁法)就是这个点的上一个点和这个点之间的“c(点上边的树的数量,k)*c(点下边的树的数量,k)”是有一点联系的,yy一下就是这个点在下一行中是作为下面的点上面的树的数量……于是修改量就是c(原来上边的树的数量+1,k)*c(原来下边的树(其实包括了这个点也就是这棵树)的数量-1,k)- c(原来上边的树的数量,k)*c(原来下边的树(其实包括了这个点也就是这棵树)的数量,k)。

然后只需要在一开始离散化一下树,再给树排个序,就差不多了,还用到了前缀和小小的搞一下。


type
arr=record
x,y:longint;
end; const
mm=; var
i,j,kk,l,n,m,w,now,tot:longint;
a:array[..]of arr;
bit:array[..]of int64;
b,d,totx,toty,hash:array[..]of longint;
c:array[..,..]of int64;
ans,ans1,ans2,ans3:int64; procedure swap(var x,y:longint);
var
i:longint;
begin
i:=x;
x:=y;
y:=i
end; function min(x,y:longint):longint;
begin
if x>y then exit(y);
exit(x)
end; function lowbit(x:longint):longint;
begin
exit(x and (-x))
end; function find(x:longint):longint;
var
l,r,mid:longint;
begin
l:=;r:=tot;
while l<=r do begin
mid:=(l+r) >> ;
if hash[mid]<x then l:=mid+
else
if hash[mid]>x then r:=mid-
else exit(mid);
end
end; procedure work;
var
i,j:longint;
begin
c[][]:=;
for i:= to w do begin
c[i,]:=;
for j:= to min(kk,i) do
c[i,j]:=(c[i-,j]+c[i-,j-]) mod mm;
end
end; procedure qsort1(l,r:longint);
var
i,j,k,mid:longint;
begin
i:=l;
j:=r;
mid:=b[(l+r) >>];
repeat
while b[i]<mid do inc(i);
while b[j]>mid do dec(j);
if i<=j then begin
swap(b[i],b[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort1(l,j);
if i<r then qsort1(i,r)
end; procedure qsort2(l,r:longint);
var
i,j,k,mid1,mid2:longint;
begin
i:=l;
j:=r;
mid1:=a[(l+r) >>].y;
mid2:=a[(l+r) >>].x;
repeat
while (a[i].y<mid1) or (a[i].y=mid1) and (a[i].x<mid2) do inc(i);
while (a[j].y>mid1) or (a[j].y=mid1) and (a[j].x>mid2) do dec(j);
if i<=j then begin
swap(a[i].x,a[j].x);
swap(a[i].y,a[j].y);
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort2(l,j);
if i<r then qsort2(i,r)
end; procedure add(x:longint;y:int64);
begin
while x<=tot do begin
bit[x]:=(bit[x]+y) mod mm;
inc(x,lowbit(x));
end
end; function ask(x:longint):int64;
var
sum:int64;
begin
sum:=;
while x> do begin
sum:=(sum+bit[x]) mod mm;
dec(x,lowbit(x));
end;
exit(sum)
end; begin
readln(n,m);
readln(w);
fillchar(totx,sizeof(totx),);
fillchar(toty,sizeof(toty),);
fillchar(d,sizeof(d),);
fillchar(bit,sizeof(bit),);
fillchar(c,sizeof(c),);
fillchar(hash,sizeof(hash),);
for i:= to w do begin
read(a[i].x,a[i].y);
b[*i-]:=a[i].x;
b[*i]:=a[i].y;
end;
qsort1(,*w);
hash[]:=b[];
tot:=;
for i:= to *w do
if b[i]<>b[i-] then begin
inc(tot);
hash[tot]:=b[i];
end;
read(kk);
work;
for i:= to w do begin
inc(totx[find(a[i].y)]);
inc(toty[find(a[i].x)]);
end;
qsort2(,w);
now:=;
ans:=;
for i:= to w do begin
j:=find(a[i].x);
if (i>) and (a[i].y=a[i-].y) then begin
inc(now);
ans1:=ask(j-)-ask(find(a[i-].x)) mod mm;
ans2:=c[now,kk]*c[totx[find(a[i].y)]-now,kk] mod mm;
ans:=(ans+ans1*ans2) mod mm;
end else now:=;
inc(d[j]);
ans3:=(c[d[j],kk]*c[toty[j]-d[j],kk]-c[d[j]-,kk]*c[toty[j]-d[j]+,kk])mod mm;
if ans3<> then add(j,ans3);
end;
if ans< then ans:=ans+mm;
writeln(ans);
end.

【以前的空间】bzoj 1227 [SDOI2009]虔诚的墓主人的更多相关文章

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

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

  2. Bzoj 1227: [SDOI2009]虔诚的墓主人 树状数组,离散化,组合数学

    1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec  Memory Limit: 259 MBSubmit: 895  Solved: 422[Submit][Statu ...

  3. BZOJ 1227 [SDOI2009]虔诚的墓主人 - 扫描线

    Solution 离散化 扫描线, 并用 $rest[i]$ 和 $cnt[i]$ 记录 第$i$列 总共有 $cnt[i]$棵常青树, 还有$rest[i]$ 没有被扫描到. 那么 第$i$ 列的方 ...

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

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

  5. bzoj1227 [SDOI2009]虔诚的墓主人(组合公式+离散化+线段树)

    1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec  Memory Limit: 259 MBSubmit: 803  Solved: 372[Submit][Statu ...

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

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

  7. 【BZOJ1227】[SDOI2009]虔诚的墓主人(线段树)

    [BZOJ1227][SDOI2009]虔诚的墓主人(线段树) 题面 BZOJ 洛谷 题解 显然发现答案就是对于每一个空位置,考虑上下左右各有多少棵树,然后就是这四个方向上树的数量中选\(K\)棵出来 ...

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

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

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

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

随机推荐

  1. CakePHP 总结

    1. 处理任何保存或获取数据的操作最好都写在模型(Model)中.这个概念通常被称为fat model. 2. 返回上一条插入记录的ID, $this->Example->getInser ...

  2. 虚拟机安装win7 64位-完美解决-费元星

    安装虚拟机是为了安装一个oracle ,在本机安装 ,本机会卡死,不是每次启动电脑都用oralce,而且有时候服务是关不干净的,所以安装在虚拟机里,需要的时候在开启,特做此记录! 费元星版权Q[971 ...

  3. facebook原生广告添加adchoice图标

    1.在需要显示adchoice的地方添加一个textview: <LinearLayout android:id="@+id/ad_ic_action" android:la ...

  4. MVC数据的注册及验证简单总结

    一.注解 注解是一种通用机制,可以用来向框架注入元数据,同时,框架不只驱动元数据的验证,还可以在生成显示和编辑模型的HTML标记时使用元数据. 二.验证注册的使用 1.Require:属性为Null或 ...

  5. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第3章.Tomcat

    第3章--Tomcat Tomcat安装与运行 Tomcat:目前最常用的基于java的web应用服务器 本课程中所有的Java代码最终都需要部署到Tomcat中运行 Tomcat的配置文件是XML的 ...

  6. [Clr via C#读书笔记]Cp16数组

    Cp16数组 一维数组,多维数组,交错数组:引用类型:P338的图非常的清楚地描述了值类型和引用类型在托管堆中的关系:越界检查: 数组初始化 数组初始化器: 四种写法 string[] names = ...

  7. Java进阶——— 线程池的原理分析

    前言 在了解线程池之前,其实首先出现的疑问是:为什么要使用线程池,其次是了解什么是线程池,最后是如何使用线程池,带着疑问去学习. 为什么要使用 前面多线程文章中,需要使用线程就开启一个新线程,简单方便 ...

  8. SpringBoot在IntelliJ IDEA下for MAC 热加载

    说在前面 热加载:文件内容变更服务器自动运行最新代码.实则在IDEA环境进行热部署后,下述过程一气呵成. 1代码变更,文件自动保存(IDEA自动保存代码,用户无需使用COMMAND+SAVE快捷键): ...

  9. vue.js学习之 如何在better-scroll加载完成后,自动滚动到最底部

    首先我们需要使用scrollTo这个方法: scrollTo(x, y, time, easing) 参数: {Number} x 横轴坐标(单位 px) {Number} y 纵轴坐标(单位 px) ...

  10. Thunder团队第五周 - Scrum会议4

    Scrum会议4 小组名称:Thunder 项目名称:i阅app Scrum Master:李传康 工作照片: 邹双黛同学在拍照,所以不在照片内. 参会成员: 王航:http://www.cnblog ...