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;
}

时间: 2024-12-11 17:48:34

HDU 5084 HeHe --找规律的相关文章

ZOJ 1037 &amp;&amp; HDU 1046 Gridland (找规律)

链接:click here 题意: 给你 一张图,问你从起点出发,最后回到起点的最短路程 思路: 当n,m有一者能够为偶数时,结果是n*m否者必有一条路需要斜着走,结果为n*m-1+1.41 代码: #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h

HDU 1847 (博弈 找规律) Good Luck in CET-4 Everybody!

多写几个就会发现3的倍数是必败点,担心可能有例外,我一直写到第15个.. 1 #include <cstdio> 2 3 int main() 4 { 5 int n; 6 while(scanf("%d", &n) == 1 && n) 7 printf("%s\n", n % 3 ? "Kiki" : "Cici"); 8 9 return 0; 10 } 代码君

hdu 5139 Formula (找规律+离线处理)

Formula Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 206    Accepted Submission(s): 83 Problem Description f(n)=(∏i=1nin−i+1)%1000000007You are expected to write a program to calculate f(n) w

hdu 4759 大数+找规律 ***

题目意思很简单. 就是洗牌,抽出奇数和偶数,要么奇数放前面,要么偶数放前面. 总共2^N张牌. 需要问的是,给了A X B Y  问经过若干洗牌后,第A个位置是X,第B个位置是Y 是不是可能的. Jason is not only an ACMer, but also a poker nerd. He is able to do a perfect shuffle. In a perfect shuffle, the deck containing K cards, where K is an

hdu 5524 二叉树找规律,二进制相关

input n 1<=n<=1e18 output 有n个结点的满二叉树有多少个不相同结点数的子树 做法:树有h=log2(n)层,最多有2h-2种(1除外),然后再n减去u重复的即可 1 #include <bits/stdc++.h> 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 #include <iostream> 6 #include <cs

HDU 2897 (博弈 找规律) 邂逅明下

根据博弈论的两条规则: 一个状态是必胜状态当且仅当有一个后继是必败状态 一个状态是必败状态当且仅当所有后继都是必胜状态 然后很容易发现从1开始,前p个状态是必败状态,后面q个状态是必胜状态,然后循环往复. 1 #include <cstdio> 2 3 int main() 4 { 5 int n, p, q; 6 while(scanf("%d%d%d", &n, &p, &q) == 3) 7 printf("%s\n", (

HDU 4639 Hehe(字符串处理,斐波纳契数列,找规律)

题目 //每次for循环的时候总是会忘记最后一段,真是白痴.... //连续的he的个数 种数 //0 1 //1 1 //2 2 //3 3 //4 5 //5 8 //…… …… //斐波纳契数列 //不连续的就用相乘(组合数)好了 #include<iostream> #include<algorithm> #include<string> #include <stdio.h> #include <string.h> #include &l

hdu 2147 kiki&#39;s game(DP(SG)打表找规律)

题意: n*m的棋盘,一枚硬币右上角,每人每次可将硬币移向三个方向之一(一格单位):左边,下边,左下边. 无法移动硬币的人负. 给出n和m,问,先手胜还是后手胜. 数据范围: n, m (0<n,m<=2000) 思路: dp[i][j]=0,说明从(i,j)这个点到时左下角先手败.dp[i][j]=1则先手胜. 然后记忆搜.但是记忆搜会超时. 搜完把整张表打出来,发现规律了,,,,然后,,,代码剩几行了. 代码: ///打表观察 /* int f[2005][2005]; int go(in

HDU 4990 Reading comprehension (找规律+矩阵快速幂)

题目链接:HDU 4990 Reading comprehension 题目给的一个程序其实就是一个公式:当N=1时 f[n]=1,当n>1时,n为奇数f[n]=2*f[n-1]+1,n为偶数f[n]=2*f[n-1]. 先不取模,计算前十个找规律.得到一个递推公式:f[n]=2*f[n-2]+f[n-1]+1 然后快速幂解决之. 给出一个神奇的网站(找数列通项):http://oeis.org/ AC代码: #include<stdio.h> #include<string.h&