HDU 5084 HeHe --找规律
题意: 给出矩阵M,求M*M矩阵的r行c列的数,每个查询跟前一个查询的结果有关。
解法: 观察该矩阵得知,令ans = M*M,则 ans[x][y] = (n-1-x行的每个值)*(n-1+y列的每个值)。直接对每个查询做n次累加(n*m=10^8的复杂度)竟然可以水过。
官方题解给的是n^2的算法,维护一个前缀和,即sum[i][j] 表示 i+j不变的所有sum[i][j]之和。
因为
ans[x][y]就是 a[y]*a[2*n-x] + .... + a[y+n-1]*a[n-x+1],乘的这部分a[i]*a[j],i+j是定值,求一个前缀和后O(1)求ans[x][y],
ans[x][y] = sum[2*n-x-2][y]-sum[n-2-x][n+y]; 这点我还不太理解。
先贴O(n*m)的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define lll __int64
using namespace std;
#define N 100007
int t[2010];
int main()
{
int n,m,i,j;
int x,y,ans;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<=2*n-2;i++)
scanf("%d",&t[i]);
scanf("%d",&m);
lll sum = 0;
ans = 0;
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
x = (x+ans)%n;
y = (y+ans)%n;
ans = 0;
for(j=0;j<n;j++)
ans += t[n-1-x+j]*t[n-1+y-j];
sum += ans;
}
cout<<sum<<endl;
}
return 0;
}
再附上meetzyc的官方做法代码:
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <string>
#include <math.h>
using namespace std;
int x,y,i,j,n,m,a[3000],e[2010][2010];
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<2*n-1;i++)
scanf("%d",&a[i]);
memset(e,0,sizeof(e));
for(i=0;i<=2*n-1;i++)
{
e[i][2*n-2]=a[i]*a[2*n-2];
for(j=2*n-1;j>=0;j--)
e[i][j]=e[i-1][j+1]+a[i]*a[j];
}
scanf("%d",&m);
__int64 sum=0;
int ans=0;
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
x = (x+ans)%n;
y = (y+ans)%n;
ans = e[2*n-x-2][y]-e[n-2-x][n+y];
sum += ans;
}
printf("%I64d\n",sum);
}
return 0;
}
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com