AFO

普及组R4

T3
链接:C

输入一个长度为n的数组a[i],下标从0开始(0到n-1)
保证n是2的整数次幂,
对于每个i (0 <= i < n)
求所有满足((i & j) == j)的a[j]之和。

对于100%的数据,1 <= n <= \(2^{20}\), 0 <= a[i] <= 1000


三维部分区间和

for (int i = 1; i <= n; i++) {  
	for (int j = 1; j <= n; j++) {  
		for (int k = 1; k <= n; k++) {  
			a[i][j][k] += a[i][j][k - 1] + a[i][j - 1][k] + a[i - 1][j][k];  
			a[i][j][k] -= a[i][j - 1][k - 1] + a[i - 1][j - 1][k] + a[i - 1][j][k - 1];  
			a[i][j][k] += a[i - 1][j - 1][k - 1];  
		}  
	}  
}  

或如下代码

for (int i = 1; i <= n; i++) {  
	for (int j = 1; j <= n; j++) {  
		for (int k = 1; k <= n; k++) {  
			a[i][j][k] += a[i][j][k - 1];  
		}  
	}  
}  
for (int i = 1; i <= n; i++) {  
	for (int j = 1; j <= n; j++) {  
		for (int k = 1; k <= n; k++) {  
			a[i][j][k] += a[i][j - 1][k];  
		}  
	}  
}  
for (int i = 1; i <= n; i++) {  
	for (int j = 1; j <= n; j++) {  
		for (int k = 1; k <= n; k++) {  
			a[i][j][k] += a[i - 1][j][k];  
		}  
	}  
}

题目好评↑

推广一下到20维

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define max(a,b) ((a)>(b) ? (a): (b))
#define RI register int 
using namespace std;

int i,m,n,j,k,a[2000001],g;

int main()
{
	scanf("%d",&n);
	for(RI i=0;i<n;i++) scanf("%d",&a[i]);
	m=n; g=0; 
	while(m)
	{
		m>>=1;
		g+=1;
	}
	for(RI i=0;i<g;i++) 
		for(RI j=(1<<i);j<n;j++)
			if(j&(1<<i)) a[j]+=a[j-(1<<i)];
    
	for(RI i=0;i<n;i++) printf("%d\n",a[i]);
}

T4

链接:D

用L图形(大小为3,也就是去掉一个角的2x2的正方形)和1x2的矩形,覆盖2xn的矩形,问有多少种方案。

覆盖要求不重不漏,整体翻转和旋转均算作不同的方案。

用于覆盖的图形可以旋转,比如可以把L旋转为Г,把1x2的矩形旋转成为2x1的矩形等。

输出方案数模10007的结果。

对于100%的数据,\(1 <= n <= 10^{100000}\)


欧拉定理可证\(x^n\equiv x^{n\%\varphi(m)}(\%m)\)
由于10007是质数,所以\(\varphi(10007)=10006\)
所以高精模后dp来做就好啦

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define M 10007
#define max(a,b) ((a)>(b) ? (a): (b))
using namespace std;
 
int i,m,n,j,k,a[100001][3];
char c[200001];
 
int qm(char *c,int k)
{
    int s=strlen(c);
    int m=0;
    for(int i=0;i<s;i++) m=m*10+c[i]-'0', m%=k;
    return m%k;
}
 
int main()
{
    gets(c);
    n=qm(c,10006);
    a[0][0]=1;
    for(i=1;i<=n;i++)
    {
        if(i>1) a[i][0]+=a[i-2][0];
        a[i][0]=(a[i][0]+a[i-1][0]+a[i-1][1]+a[i-1][2])%M;
        if(i>1) a[i][1]+=a[i-2][0];
        a[i][1]=(a[i][1]+a[i-1][2])%M;
        if(i>1) a[i][2]+=a[i-2][0];
        a[i][2]=(a[i][2]+a[i-1][1])%M;
    }
    printf("%d",a[n][0]);
}
posted @ 2019-10-12 16:02  ZUTTER☮  阅读(101)  评论(0编辑  收藏  举报