hdu2018多校赛第四场1005 Matrix from Arrays

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6336

题目的意思就是用一个数列来产生一个无限矩阵,给出一系列询问,求所给出子矩阵的元素和。

一个比较好找的规律是M[x][y]=a[((x+y)*(x+y+1)/2+x)%L],于是一开始我把子矩阵按照斜线来求和,然后妥妥超时了……

超时代码:

#include
#include
#include
using namespace std;
int id(long long x,long long y,int n)
{
    return ((x+y)*(x+y+1)/2+x)%n;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,q,a[15];
        long long sum=0;
        scanf("%d",&n);
        for(int i=0;i=l)
                    {
                        ans+=(l/n)*sum;
                        int t=id(x1+i-1,y2,n);
                        for(int j=0;j

TLE之后重新找规律……由样例的1 10 100构成的矩阵发现整个矩阵其实是L*L的矩阵拼成的,也就是说M[x][y]=M[x%L][y%L],然后把要求的矩阵分块,结果又WA了→_→

后来才发现原来偶数个数的数列(比如1 2)构成的矩阵是2L*2L的矩阵拼成的,两种情况合并就是M[x][y]=M[x%2L][y%2L],果然还是要多尝试几组样例呀。

AC代码:

#include
#include
#include
using namespace std;
int id(long long x,long long y,int n)
{
    return ((x+y)*(x+y+1)/2+x)%n;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,q,a[15],block[30][30],band[30],stripe[30];
        long long sum=0;
        memset(band,0,sizeof(band));
        memset(stripe,0,sizeof(stripe));
        scanf("%d",&n);
        for(int i=0;i

 

你可能感兴趣的:(hdu)