zoukankan      html  css  js  c++  java
  • GJGHFD的蛇 题解 [容斥]

    GJGHFD的蛇

    Description:

    ​ GJGHFD 的农田中有 (n) 条蛇,第 (i) 条蛇位于位置 ((x_i, y_i)) ,并且具有一个危险度 (b_i). 现在,GJGHFD 手中有 m 把枪,他决定给每把枪指定一条蛇作为目标,并且每把枪的目标互不相同. 指定目标后,这 (m) 把枪就会同时开枪.
    ​ 对于一个指定目标的方案,在 GJGHFD 开枪后,第 (i) 条蛇被影响到当且仅当有一把枪指向它,或者有一把枪指向 (j) ,并且 (max(|x_i−x_j |, |y_i−y_j |) leq r),其中 (r) 是这 (m) 把枪的共有属性. 如果第 (i) 条蛇被影响到,则 GJGHFD 将获得分数 (b_i). 这些分数之和就是此方案的总得分. 求所有指定目标的方案的总得分的平方和.
    ​ 因为答案可能较大,请输出其对 (10^9 + 7) 取模的结果.

    Input:

    ​ 第一行三个整数 (n, m, r) .
    ​ 接下来 (n) 行,每行三个整数 (x_i, y_i, b_i) ,描述一条蛇.

    Output:

    ​ 一行一个整数表示答案.

    Sample Input:

    4 2 1
    1 1 10
    2 2 20
    2 3 30
    5 2 40
    

    Sample Output:

    33800
    

    Hint:

    ​ 对于(20\%)的数据,(1 leq m leq n leq 10)

    ​ 对于(50\%)的数据,(1 leq m leq n leq 200)

    ​ 对于(100\%)的数据,(1 leq m leq n leq 3 imes 10^3,0 leq r < 10^{3},1 leq x_i,y_i leq 10^3,1 leq b_i leq 10^6)

    ​ 时间限制: (1s)

    ​ 空间限制: (512M)

    题目分析:

    ​ 设选出的m条蛇所能影响到的所有蛇的集合为(egin{Bmatrix}b_1,b_2,...,b_kend{Bmatrix}).

    ​ 我们可以把((sum_{i=1}^kb_{p_i})^2)可以拆成:(sum_{i=1}^k sum_{j=1}^k b_{p_i} imes b_{p_j}).

    ​ 于是我们可以想到给每一对(b_i imes b_j)计算贡献,然后求个和即可。

    ​ 我们设两条蛇(i,j)在一种方案中都被影响到的可能方案数为(x).

    ​ 我们考虑容斥,设 (a=) 选中之后只能影响(i),不能影响(j)的蛇的个数, (b=) 选中之后不能影响(i),只能影响(j)的蛇的个数, (c=) 选中之后既能影响(i),又能影响(j)的蛇的个数.

    ​ 则(x=C_n^m-C_{n-a-c}^m-C_{n-b-c}^m+C_{n-a-b-c}^m)

    ​ 即:总方案(-)不合法方案.

    ​ 而(a,b,c)可以通过预处理前缀和(O(1))计算,于是我们可以用(O(n^2))的复杂度过了此题。

    ​ 代码如下(马蜂很丑,不喜勿喷)——

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define Tp template<typename T>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define maxn 3005
    #define LL long long
    using namespace std;
    int n,m,r,x[maxn],y[maxn],v[maxn],ans,maxx,maxy,f[maxn][maxn],sum[maxn][maxn];const int p=1e9+7;
    inline int S(int sx,int sy,int tx,int ty){sx=max(1,sx);tx=min(maxx,tx);sy=max(1,sy);ty=min(maxy,ty);if(sx>tx||sy>ty) return 0;return sum[tx][ty]-sum[sx-1][ty]-sum[tx][sy-1]+sum[sx-1][sy-1];}
    inline int calc(int a,int b,int c){int x=f[n][m]-f[n-a-c][m];(x<0)&&(x+=p);x-=f[n-b-c][m],(x<0)&&(x+=p);x+=f[n-a-b-c][m];(x>=p)&&(x-=p);return x;}
    class FileInputOutput
    {
    	private:
    		static const int S=1<<21;
    		#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
    		#define pc(ch) (Ftop!=Fend?*Ftop++=ch:(fwrite(Fout,1,S,stdout),*(Ftop=Fout)++=ch))
    		char Fin[S],Fout[S],*A,*B,*Ftop,*Fend; int pt[25];
    	public:
    		FileInputOutput(void) { Ftop=Fout; Fend=Fout+S; }
    		Tp inline void read(T& x)
    		{
    			x=0; char ch; while (!isdigit(ch=tc()));
    			while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
    		}
    		Tp inline void write(T x,const char& ch)
    		{
    			if (x<0) pc('-'),x=-x; RI ptop=0; while (pt[++ptop]=x%10,x/=10);
    			while (ptop) pc(pt[ptop--]+48); pc(ch);
    		}
    		inline void flush(void)
    		{
    			fwrite(Fout,1,Ftop-Fout,stdout);
    		}
    		#undef tc
    		#undef pc
    }F;
    int main(){
    //	freopen("data2.in","r",stdin);
    	F.read(n),F.read(m),F.read(r);for(register int i=1;i<=n;i++) F.read(x[i]),F.read(y[i]),F.read(v[i]),sum[x[i]][y[i]]++,maxx=max(maxx,x[i]),maxy=max(maxy,y[i]);
    	for(register int i=1;i<=maxx;i++) for(register int j=1;j<=maxy;j++) sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    	f[0][0]=1;for(register int i=1;i<=n;i++){f[i][0]=1;for(register int j=1;j<=m;j++) f[i][j]=f[i-1][j]+f[i-1][j-1],(f[i][j]>=p)&&(f[i][j]-=p);}
    	for(register int i=1,xx;i<=n;i++) xx=f[n][m]-f[n-S(x[i]-r,y[i]-r,x[i]+r,y[i]+r)][m],(xx<0)&&(xx+=p),ans+=1ll*xx*v[i]%p*v[i]%p,(ans>=p)&&(ans-=p);
    	for(register int i=1;i<n;i++) for(register int j=i+1;j<=n;j++){
    		int c=S(max(x[i]-r,x[j]-r),max(y[i]-r,y[j]-r),min(x[i]+r,x[j]+r),min(y[i]+r,y[j]+r)),a=S(x[i]-r,y[i]-r,x[i]+r,y[i]+r)-c,b=S(x[j]-r,y[j]-r,x[j]+r,y[j]+r)-c;
    		ans+=2ll*calc(a,b,c)*v[i]%p*v[j]%p;(ans>=p)&&(ans-=p);
    	}
    	F.write(ans,'
    ');return F.flush(),0;
    }
    
    
  • 相关阅读:
    [Android Studio] Android studio 多渠道打包(超简洁版)
    AlarmManager、PendingIntent的使用附件Home监听十分钟后再度启动应用取消服务
    share Windows下AndroidStudio 中使用Git(AndroidStudio项目于GitHub关联)
    Flex 调用webService
    mac下安装应用及常用快捷键
    mac下设置maven环境
    0302关于软件工程的思考
    文法评论
    C语言文法
    44-小组词法分析
  • 原文地址:https://www.cnblogs.com/jiangxuancheng/p/14237725.html
Copyright © 2011-2022 走看看