• 20180516模拟赛T1——queen


    题解

    这题显然是(总方案数不可行方案数总方案数-不可行方案数)(直接算是无规则的)。总方案数是(n^2m^2),于是问题就在于不可行的方案数。

    若queen落在一个点上,则横竖是十分好求的((n+m)),如果能求出斜的两条就完美了。

    我们发现,这种方法Q的位置会加三次,于是我们可以在最后统一减(3nm)

    然后比较困难的是求斜的边。

    假定我们求从左上到右下线的总长度。钦定(nle m)。于是就得到这样一张图:

    绿色区域的点和竖线是等效的,主要是白色区域。

    对于每一条斜线,我们发现第(i)线上的点的个数是(i),于是我们就可以很容易地得出不可行方案数的总和为,(sum_{i=1}^n i^2)有于有4块(反着还有两块),故要乘4。

    于是就是要快速求出(sum_{i=1}^n i^2)。。(sum_{i=1}^n i^2 = frac{n(n+1)(2n+1)}{6})由于我太菜了,只会归纳法,本想看一下如何现场手推(想看如何现场推的可以点这里)。

    于是最后就是高精的问题了,可以不压位。

    代码

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int width = 4;
    const int mod = 1e4;
    
    typedef long long LL;
    
    struct HugeInt
    {
    	int a[50];
    	int len;
    
    	inline void clear()
    	{
    		memset(a, 0, sizeof(a));
    		len = 0;
    	}
    };
    
    HugeInt operator + (HugeInt a, HugeInt b)
    {
    	HugeInt c;
    	c.clear();
    	int maxlen = max(a.len, b.len);
    	for(int i = 0; i < maxlen; ++i)
    	{
    		c.a[i] += a.a[i]+b.a[i];
    		c.a[i+1] += c.a[i]/mod;
    		c.a[i] %= mod;
    	}
    	c.len = maxlen;
    	while(c.a[c.len])
    		c.len++;
    	return c;
    }
    
    HugeInt operator - (HugeInt a, HugeInt b)
    {
    	HugeInt c;
    	c.clear();
    	c.len = a.len;
    	for(int i = 0; i < c.len; ++i)
    	{
    		c.a[i] += a.a[i]-b.a[i];
    		if(c.a[i]<0)
    		{
    			a.a[i+1]--;
    			c.a[i] += mod;
    		}
    	}
    	while(!c.a[c.len-1] && c.len>=1)
    		c.len--;
    	return c;
    }
    
    HugeInt operator * (HugeInt a, HugeInt b)
    {
    	HugeInt c;
    	c.clear();
    	for(int i = 0; i < a.len; ++i)
    		for(int j = 0; j < b.len; ++j)
    			c.a[i+j] += a.a[i] * b.a[j];
    	c.len = a.len + b.len - 1;
    	for(int i = 0; i < c.len; ++i)
    	{
    		c.a[i+1] += c.a[i]/mod;
    		c.a[i] %= mod;
    	}
    	while(c.a[c.len])
    		c.len++;
    	return c;
    }
    
    bool operator < (HugeInt a, HugeInt b)
    {
    	if(a.len != b.len)
    		return a.len < b.len;
    	else
    	{
    		for(int i = a.len-1; i >= 0; --i)
    		{
    			if(a.a[i] != b.a[i])
    				return a.a[i] < b.a[i];
    		}
    	}
    	return false;
    }
    
    HugeInt give(long long a)
    {
    	HugeInt re;
    	re.clear();
    	while(a)
    	{
    		re.a[re.len++] = a%mod;
    		a /= mod;
    	}
    	return re;
    }
    
    HugeInt operator + (HugeInt a, LL b)
    {
    	return a + give(b);
    }
    
    HugeInt operator + (LL a, HugeInt b)
    {
    	return b + a;
    }
    
    HugeInt operator * (HugeInt a, LL b)
    {
    	return a * give(b);
    }
    
    HugeInt operator * (LL a, HugeInt b)
    {
    	return b * a;
    }
    
    HugeInt operator - (HugeInt a, LL b)
    {
    	return a - give(b);
    }
    
    HugeInt operator / (HugeInt a,LL b)
    {
    	HugeInt ans;
    	ans.clear();
    	ans=a;
    	LL my=0;
    	for(int i=ans.len-1; i>=0; i--)
    	{
    		ans.a[i]+=my;
    		my=ans.a[i]%b*mod;
    		ans.a[i]/=b;
    	}
    	while(!ans.a[ans.len-1])
    		ans.len--;
    	return ans;
    }
    
    void print(HugeInt a)
    {
    	printf("%d", a.a[a.len-1]);
    	for(int i = a.len-2; i>=0; --i)
    		printf("%04d", a.a[i]);
    }
    
    void solve(LL n, LL m)
    {
    	if(m < n)
    		swap(n, m);
    	HugeInt nn = give(n);
    	HugeInt mm = give(m);
    	print(nn*nn*mm*mm-(nn*(nn+1)*(nn*2+1)/3*2+nn*nn*2*(mm-nn-1)+(nn+mm)*nn*mm-3*nn*mm));
    	puts("");
    }
    
    int main()
    {
    	freopen("queen.in", "r", stdin);
    	freopen("queen.out", "w", stdout);
    	int nmn;
    	long long a, b;
    	scanf("%d", &nmn);
    	while(nmn--)
    	{
    		scanf("%lld%lld", &a, &b);
    		solve(a, b);
    	}
    	return 0;
    }
    
  • 相关阅读:
    C++快速排序
    C++冒泡排序
    为什么Excel创建一个新的工作簿就会初始化三个worksheet
    为什么游戏需要英雄
    2015.11.18——Lua中文教程
    [国家集训队2012]JZPFAR
    后缀数组小结?
    [BZOJ 2738]矩阵乘法
    [BZOJ 3221][Codechef FEB13] Obserbing the tree树上询问
    [BZOJ 4999]This Problem Is Too Simple!
  • 原文地址:https://www.cnblogs.com/pfypfy/p/9048209.html
Copyright © 2020-2023  润新知