题解: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. spring源码-Aware-3.4

    一.Aware接口,这个也是spring的拓展之一,为啥要单独拿出来讲呢,因为他相比于BeanFactoryPostProcessor,BeanPostProcessor的实用性更加高,并且在具体的业 ...

  2. Android7.0 应用内升级

    Android7.0应用内升级 最近线上项目在7.0机器上出现应用内升级失败,原来是由于Android7.0权限问题导致. 如果项目的 targetSdkVersion>=24 在处理应用内升级 ...

  3. Java子类与父类之间的类型转换

    1.向上转换 父类的引用变量指向子类变量时,子类对象向父类对象向上转换.从子类向父类的转换不需要什么限制,只需直接蒋子类实例赋值给父类变量即可,这也是Java中多态的实现机制. 2.向下转换 在父类变 ...

  4. 「LeetCode」0002-Longest Substring Without Repeating Characters(C++)

    分析 贪心思想.注意更新每次判断的最长不同子串的左区间的时候,它是必须单调增的(有时候会在这里翻车). 代码 关掉流同步能有效提高速度. static const auto io_sync_off = ...

  5. Qt-Qml-隐藏标题栏-程序依附任务栏

    最近换工作,直接欢动qml这边来了,以后可能会有更多关于qml的文章 今天第一个,qml下面怎么隐藏标题栏 第一种方法是在使用QQuickView加载qml文件的话,这里就可以使用QQuickView ...

  6. 牛客网暑期ACM多校训练营(第五场):F - take

    链接:牛客网暑期ACM多校训练营(第五场):F - take 题意: Kanade有n个盒子,第i个盒子有p [i]概率有一个d [i]大小的钻石. 起初,Kanade有一颗0号钻石.她将从第1到第n ...

  7. 手把手教你封装 Vue 组件,并使用 npm 发布

    Vue 开发插件 开发之前先看看官网的 开发规范 我们开发的之后期望的结果是支持 import.require 或者直接使用 script 标签的形式引入,就像这样: // 这里注意一下包的名字前缀是 ...

  8. 下落的树叶 (The Falling Leaves UVA - 699)

    题目描述: 原题:https://vjudge.net/problem/UVA-699 题目思路: 1.依旧二叉树的DFS 2.建树过程中开个数组统计 //紫书源代码WA AC代码: #include ...

  9. Java VisualVM使用

    Java VisualVM Java VisualVM官网 Java VisualVM介绍 Java VisualVM is a tool that provides a visual interfa ...

  10. IDEA搭载Tomcat使用JSTL连接Oracle数据库

    1.在IDEA中,JSTL库添加到WEB-INF/lib下面可以直接在JSP页面上通过 <%@ taglib uri="http://java.sun.com/jsp/jstl/cor ...