BZOJ-1227 虔诚的墓主人 树状数组+离散化+组合数学
来源:互联网 发布:mac向u盘复制文件 编辑:程序博客网 时间:2024/05/03 13:46
1227: [SDOI2009]虔诚的墓主人
Time Limit: 5 Sec Memory Limit: 259 MB
Submit: 914 Solved: 431
[Submit][Status][Discuss]
Description
小W 是一片新造公墓的管理人。公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地。当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地。为了体现自己对主的真诚,他们希望自己的墓地拥有着较高的虔诚度。一块墓地的虔诚度是指以这块墓地为中心的十字架的数目。一个十字架可以看成中间是墓地,墓地的正上、正下、正左、正右都有恰好k 棵常青树。小W 希望知道他所管理的这片公墓中所有墓地的虔诚度总和是多少
Input
第一行包含两个用空格分隔的正整数N 和M,表示公墓的宽和长,因此这个矩形公墓共有(N+1) ×(M+1)个格点,左下角的坐标为(0, 0),右上角的坐标为(N, M)。第二行包含一个正整数W,表示公墓中常青树的个数。第三行起共W 行,每行包含两个用空格分隔的非负整数xi和yi,表示一棵常青树的坐标。输入保证没有两棵常青树拥有相同的坐标。最后一行包含一个正整数k,意义如题目所示。
Output
包含一个非负整数,表示这片公墓中所有墓地的虔诚度总和。为了方便起见,答案对2,147,483,648 取模。
Sample Input
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
Sample Output
6
HINT
图中,以墓地(2, 2)和(2, 3)为中心的十字架各有3个,即它们的虔诚度均为3。其他墓地的虔诚度为0。 对于30%的数据,满足1 ≤ N, M ≤ 1,000。对于60%的数据,满足1 ≤ N, M ≤ 1,000,000。对于100%的数据,满足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。
Source
题解: 一看数据范围,肯定要离散化,熟练的打上,然后开始做。 这里要用到组合来进行求值,大体上的思路是: 如果a,b在同一行,则ans+=c(l[a]+1(包括a),k)*c(r[b]+1,k)再分别乘上ab间的每一个点的c(u[i],k)*c(d[i],k)
l[a],r[a],u[a],d[a]表示一个点上下左右的点数,可以预处理,也可以边做边记录
需要优化时间复杂度,于是要用树状数组维护a到b所有点的c(u[i],k)*c(d[i],k)之和
从左往右处理某行的某一个点时,要将树状数组中该点横坐标位置上的数进行修改
修改的值为就是现在的c(u[i],k)*c[d[i],k]减去原来的,也就是c(u[i],k)*c[d[i],k]-c(u[i]+1,k)*c[d[i]-1,k]
后来发现自己的离散似乎有些不适合,只能1AC19WA,于是改成黄学长的方式才能过
code:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f;}#define maxw 100010#define p 2147483648LLint n,m,w,k,l;struct data{ int x,y; bool operator < (const data & A) const { if (y==A.y) return x<A.x; return y<A.y; }}tr[maxw];long long tree[maxw*2],C[maxw*2][15],ans;int ls[maxw*2],cnt,num,now[maxw*2];int xx[maxw*2],yy[maxw*2];int lowbit(int x){ return x&(-x);}void add(int x,int dat){ for (int i=x; i<=w*2; i+=lowbit(i)) tree[i]=(tree[i]+dat)%p;}long long query(int x){ long long re=0; for (int i=x; i>0; i-=lowbit(i)) re=(re+tree[i])%p; return re;}int getloc(int dat){ int l=1,r=cnt; while (l<=r) { int mid=(l+r)>>1; if (ls[mid]<dat) l=mid+1; else if (ls[mid]>dat) r=mid-1; else return mid; }}void getC(){ C[0][0]=1; for (int i=1; i<=w; i++) { C[i][0]=1; for (int j=1; j<=min(k,i); j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%p; }}int main(){ n=read(),m=read(); w=read(); for (int i=1; i<=w; i++) ls[++cnt]=tr[i].x=read(),ls[++cnt]=tr[i].y=read(); k=read(); sort(ls+1,ls+cnt+1); //for (int i=2; i<=cnt; i++) if (ls[i]!=ls[i-1]) ls[++num]=ls[i]; //for (int i=1; i<=w; i++) tr[i].x=getloc(tr[i].x),tr[i].y=getloc(tr[i].y); for (int i=1; i<=w; i++) xx[getloc(tr[i].x)]++,yy[getloc(tr[i].y)]++; getC(); sort(tr+1,tr+w+1); //for (int i=1; i<=w; i++) //printf("%d %d\n",getloc(tr[i].x),getloc(tr[i].y)); for(int i=1;i<=w;i++) { if(i>1 && tr[i].y==tr[i-1].y) l++,ans+=(query(getloc(tr[i].x)-1)-query(getloc(tr[i-1].x)))*(C[l][k]*C[yy[getloc(tr[i].y)]-l][k]),ans%=p; else l=0; int loc=getloc(tr[i].x); now[loc]++; int delta=(C[now[loc]][k]*C[xx[loc]-now[loc]][k]-C[now[loc]-1][k]*C[xx[loc]-now[loc]+1][k])%p; add(loc,delta); } if (ans<0) ans+=p; printf("%lld\n",ans); return 0;}
- BZOJ-1227 虔诚的墓主人 树状数组+离散化+组合数学
- 1227: [SDOI2009]虔诚的墓主人 树状数组+离散化
- 【bzoj1227】【SDOI2009】【虔诚的墓主人】【组合数学+树状数组】
- BZOJ 1227: [SDOI2009]虔诚的墓主人 树状数组 组合数
- [bzoj]1227: [SDOI2009]虔诚的墓主人【树状数组】
- [BZOJ]1227: [SDOI2009]虔诚的墓主人 树状数组
- [BZOJ1227]虔诚的墓主人 树状数组+组合数计数
- bzoj1227 虔诚的墓主人 树状数组
- BZOJ 1227: [SDOI2009]虔诚的墓主人 数状数组
- bzoj-1227 虔诚的墓主人
- [BZOJ 1227] 虔诚的墓主人
- 【BZOJ 1227】 [SDOI2009]虔诚的墓主人
- bzoj 1227: [SDOI2009]虔诚的墓主人
- bzoj 1227: [SDOI2009]虔诚的墓主人
- bzoj1227 [SDOI2009]虔诚的墓主人(组合公式+离散化+线段树)
- [杂题 离散 扫描线] BZOJ1227: [SDOI2009]虔诚的墓主人
- [SDOI2009]虔诚的墓主人
- BZOJ1227: [SDOI2009]虔诚的墓主人
- java socket 编程
- vs2010下配置pthread环境详解
- mysql 连接字符串与SQL不同
- Objective - C类的扩展
- 【笔记】mac配置文件
- BZOJ-1227 虔诚的墓主人 树状数组+离散化+组合数学
- 题二 源代码编译:拓扑排序
- 释迦牟尼佛和阿弥陀佛有何区别?
- 安全擦除swap分区
- JAVA native method简介
- 安卓屏幕适应
- 希尔排序C++
- AngularJS 控制器
- Uva216—— Getting in Line