zoukankan      html  css  js  c++  java
  • 【BZOJ 1227】 [SDOI2009]虔诚的墓主人

    一贯的链接: http://dev.luogu.org:8888/wiki/show?name=题解+P2154

    又是神题!!!!

    注意 他说自然溢出! 坑死我了啊 自然溢出会变负数!!! 还要自己加上MO啊!!!

    代码

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    #define MO 2147483648
    struct H
    {
    	int x,y;
    	int UP,DOWN;  //这个点上面有多少棵树(包括这个点) ,这个点下面有多少棵树(不包括这个点) 
    	int id;
    }a[100000+1+1];
    bool cmpx(H a,H b){ if(a.x==b.x) return a.y<b.y;return a.x<b.x;}
    bool cmpy(H a,H b){ if(a.y==b.y) return a.x<b.x;return a.y<b.y;}
    int n,m,w,k;
    int s[100000+1],id[100000+1],cnt=0;  //树状数组 离散 
    int c[100000+1][10+1];  //组合 
    int R[100000+1];  //每行 树的数量 
    int lowbit(int x){return x&-x;}
    int Sum(int x)
    {
    //	cout<<x<<endl;
    	int ans=0;
    	while(x>=1)
    		ans+=s[x],x-=lowbit(x);
    	return ans;	
    }
    void Add(int x,int d)
    {
    	while(x<=cnt)
    		s[x]+=d,x+=lowbit(x);
    }
    int main()
    {
    	scanf("%d %d %d",&n,&m,&w);
    	for(int i=1;i<=w;i++) scanf("%d %d",&a[i].x,&a[i].y);
    	a[0].x=a[0].y=a[w+1].x=a[w+1].y=-1;
    	scanf("%d",&k);
    
    	//组合
    	c[0][0]=1; 
    	for(int i=1;i<=w;i++)
    	{
    		c[i][0]=1;
    		for(int j=1;j<=k;j++)
    			c[i][j]=c[i-1][j-1]+c[i-1][j];
    	}	
    	//离散  x  id[] 
    	//处理 每颗树 上下 各有多少棵树 
    	sort(a+1,a+w+1,cmpx);
    	for(int i=1;i<=w;i++) if(a[i].x==a[i-1].x) a[i].DOWN=a[i-1].DOWN+1,a[i].id=cnt; else a[i].id=++cnt;
    	for(int i=w;i>=1;i--) if(a[i].x==a[i+1].x) a[i].UP=a[i+1].UP+1;else a[i].UP=1;
    	// 每一行有多少颗树 
    	int tmp=0;
    	sort(a+1,a+w+1,cmpy); 
    	for(int i=1;i<=w;i++)
    	{
    		tmp++; 
    		if(a[i].y!=a[i+1].y) R[i]=tmp,tmp=0;
    	}
    	for(int i=w;i>=1;i--) if(a[i].y==a[i+1].y) R[i]=R[i+1];
    	//求和 
    	tmp=0;
    	int ans=0;
    	for(int i=1;i<=w;i++)
    	{
    		tmp++; 
    		if(a[i].y!=a[i+1].y)	
    			tmp=0;
    		else
    			ans+=(c[tmp][k]*c[ R[i]-tmp ][k])*(Sum(a[i+1].id-1)-Sum(a[i].id));
    		Add(a[i].id,  - c[a[i].UP][k] * c[a[i].DOWN][k] + c[a[i].UP-1][k] * c[a[i].DOWN+1][k] );
    	}
    	while(ans<0) ans+=MO;  //自然溢出会变负数!!!!! 
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    centOS7 mini配置linux服务器(三) 配置防火墙以及IPtables切换
    Linux的常用基本命令。
    centOS7 mini配置linux服务器(二) 配置IP
    分享Git的一些个人配置
    Firefox中Vimperator插件配置
    Linux下修改键盘默认布局
    Git对于单个文件的分批提交方式的使用
    Linux安装Monaco字体
    浮点与整形在GUI下的相关思考
    2D简单图形相关算法罗列
  • 原文地址:https://www.cnblogs.com/ofsxb/p/5125355.html
Copyright © 2011-2022 走看看