题解: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. Redis系列六 Redis事务

    Redis事务 1.介绍 在Redis事务中可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 2.事务的作用 一个队列中, ...

  2. Docker - 常用命令集

    启动容器 docker run -d -p 58080:8080 -p 58000:8000 --name mytomcat1.0 -v /root/webapps/:/opt/apache-tomc ...

  3. NGUI制作流光效果

    效果展示: 技巧: 1.勾选UIPanel下的Normal启用UI的法线贴图,并建立带有法线贴图的UI对象(此处用NGUI自带的Reflector.Atlas中的图作为UI). 2.建立点光源并为其添 ...

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

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

  5. ionic LoadingController 模块使用

    html 代码: <ion-header> <ion-navbar> <ion-title>Loading</ion-title> </ion-n ...

  6. mouseover 和 mouseout 事件是可以冒泡的 取消

    mouseover 和 mouseout 事件是可以冒泡的,子元素上触发的事件会冒泡到父元素上.可以改用 mouseleave 和 mouseenter 事件,这两个事件不冒泡.

  7. C Program基础-宏定义

    写好c语言,漂亮的宏定义是非常重要的,我们在阅读别人工程时,往往能看到大量的宏定义,宏定义可以增加代码的可读性,也能增加代码的可移植性,一个好的宏定义甚至是一件艺术品.今天我们就来看看宏定义的方方面面 ...

  8. H5页面 绝对定位元素被 软键盘弹出时顶起

    H5页面 绝对定位元素被 软键盘弹出时顶起 在h5页面开发的过程中,我们可能会遇到下面这个问题,当页面中有输入框的时候,系统自带的软盘会把按钮挤出原来的位置.那么我们该怎么解决呢?下面列出一下的方法: ...

  9. 使用 letter-space 后文字不能居中解决

    letter-space:2em; text-align: center; 使用letter-space后和上面的字体对比明显没有居中: 选定元素后发现,每个字后面都被加了2em,不是不能居中而是因为 ...

  10. 关于智能指针类型shared_ptr的计数问题

    一.关键 每个shared_ptr所指向的对象都有一个引用计数,它记录了有多少个shared_ptr指向自己 shared_ptr的析构函数:递减它所指向的对象的引用计数,如果引用计数变为0,就会销毁 ...