E. 虔诚的墓主人

题目描述

小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棵

树状数组+离散化+组合数

真的是个神仙题,主要是代码打得太乱(逢离散化必挂),颓了测试点才调出来…

M,N远大于W,铁定要离散化,然后W2其实就可以AC了(数据有点水啊),但是是可以被卡掉的,

对于一个墓地,设他的上下左右分别有u[],d[],l[],r[]颗树,则他的虔诚度=C(u,k)*C(d,k)*C(l,k)*C(r,k),

对于同一行两颗常青树a,b之间的空地,他们的l[]和r[]是一样的,所以可以考虑用树状数组维护这一行的每个点C(u,k)*C(d,k)的前缀和,

ans+=C(l[a]+1,k)*C(r[b]+1,k)*(ask(b-1)-ask(a)),换行时单点修改即可。

#include<map>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define mod 2147483648
#define ma(x) memset(x,0,sizeof(x))
using namespace std;
LL N,M,W,k;
LL C[100010][15];
LL xi[100010],yi[100010],tx[100010],ty[100010];
LL h[100010],l[100010];
LL ss[100010],xx[100010];
LL maxx,maxy;
vector<int> inc[100010];
LL Ch[100100];
int lowbit(int x){return x&(-x);}
void add(int x,LL y);
LL ask(int x);
void xget_C(int maxn);
signed main()
{
// freopen("25.in","r",stdin); scanf("%lld%lld%lld",&N,&M,&W);
for(int i=1;i<=W;i++)scanf("%d%d",&xi[i],&yi[i]),tx[i]=xi[i],ty[i]=yi[i];
cin>>k;
xget_C(100000);
sort(xi+1,xi+W+1);
maxx=unique(xi+1,xi+W+1)-xi-1;
sort(yi+1,yi+W+1);
maxy=unique(yi+1,yi+W+1)-yi-1;
for(int i=1;i<=W;i++)
{
int t1=lower_bound(xi+1,xi+maxx+1,tx[i])-xi;
int t2=lower_bound(yi+1,yi+maxy+1,ty[i])-yi;
h[t2]++,l[t1]++;
inc[t2].push_back(t1);
}
for(int i=1;i<=maxy;i++)
sort(inc[i].begin(),inc[i].end());
for(int i=1;i<=maxx;i++)ss[i]=l[i];
LL ans=0;
for(int i=1;i<=maxy;i++)
{
for(int j=0;j<inc[i].size();j++)
{
ss[inc[i][j]]--,xx[inc[i][j]]++;
LL te1=(C[ss[inc[i][j]]][k]*C[xx[inc[i][j]]][k])%mod,
te2=(C[ss[inc[i][j]]+1][k]*C[xx[inc[i][j]]-1][k])%mod;
add(inc[i][j],(te1-te2+mod)%mod);
}
if(i>k && h[i]>=2*k)
for(int j=k;j+k<=inc[i].size();j++)
if(j && inc[i][j]!=inc[i][j-1]+1)
ans=(ans+C[j][k]*C[inc[i].size()-j][k]*(ask(inc[i][j]-1)-ask(inc[i][j-1])))%mod;
}
cout<<(ans%mod+mod)%mod<<endl;
}
void xget_C(int maxn)
{
C[0][0]=1;
for(int i=1;i<=maxn;i++)
{
C[i][0]=1;
for(int j=1;j<=min(i,11);j++)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
void add(int x,LL y)
{
while(x<=maxx)
{
Ch[x]=(Ch[x]+y)%mod;
x+=lowbit(x);
}
}
LL ask(int x)
{
LL ans=0;
while(x)
{
ans=(ans+Ch[x])%mod;
x-=lowbit(x);
}
return ans;
}

【BZOJ1227】[SDOI2009]虔诚的墓主人的更多相关文章

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

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

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

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

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

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

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

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

  5. [bzoj1227] [SDOI2009]虔诚的墓主人

    终于填上了这个万年巨坑....从初二的时候就听说过这题...然后一直不敢写QAQ 现在感觉也不是很烦(然而我还是写麻烦了 离散化一波,预处理出组合数什么的.. 要维护对于当前行,每列上方和下方节点凑出 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 学习JDK1.8集合源码之--TreeMap

    1. TreeMap简介 TreeMap继承自AbstractMap,实现了NavigableMap.Cloneable.java.io.Serializable接口.所以TreeMap也是一个key ...

  2. LINUX访问文件配置

    访问文件 /etc/host.conf 告诉网络域名服务器如何查找主机名.(通常是 /etc/hosts,然后就是名称服务器:可通过 netconf 对其进行更改) /etc/hosts 包含(本地网 ...

  3. 洛谷P2826 [USACO08NOV]光开关Light Switching [2017年6月计划 线段树02]

    P2826 [USACO08NOV]光开关Light Switching 题目描述 Farmer John tries to keep the cows sharp by letting them p ...

  4. Flask – SQLite:增加成员

    目录 简介 结构 展示 技术 运行 代码 创建数据库表单 views视图 models模块 home主页 list列表页 result消息结果页 studentst添加成员 简介 结构 $ tree ...

  5. Django项目:CRM(客户关系管理系统)--13--05PerfectCRM实现King_admin注册功能获取内存02

    admin_class.model = modelself.registered_sites[app_name][model_name] = admin_class #注册APP #base_admi ...

  6. 【笔记】http协议笔记

    本文是本人在复习http协议时,手动整理的资料,以备后续查阅. http(hypertext transfer protocol):超文本协议.是万维网(world wide web,www,也简称为 ...

  7. pip 异常问题

    场景:安装的python版本为3.6.4 在使用pip命令时,出现错误:Did not provide a command 如下图所示: 解决办法:pip带上后缀.exe 为什么会出现这种情况? 主要 ...

  8. GCC/GDB学习

    GCC学习 1.gcc是根据后缀名来区分文件的 .c : c语言源文件 .a : 目标文件构成的库文件 .C/.cc/.cxx : c++源文件 .h : 头文件 .i : 预处理过的C源文件 .ii ...

  9. StatusBar用法

    一.StatusBar组件介绍 StatusBar 是 React Native 0.20 起新增的跨平台组件,它可以用来设置并动态改变设备的状态栏显示特性. StatusBar 组件可以同时加载多个 ...

  10. [ 转]Linux进程关系

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux的进程相互之间有一定的关系.比如说,在Linux进程基础中,我们看到,每 ...