hdu 5084 前缀和预处理

http://acm.hdu.edu.cn/showproblem.php?pid=5084

给出矩阵M,求M*M矩阵的r行c列的数,每个查询跟前一个查询的结果有关。

观察该矩阵得知,令ans = M*M,则 ans[x][y] = (n-1-x行的每个值)*(n-1+y列的每个值),即:

ans[x][y] = t[y] * t[2*n - 2 - x] +....+ t[y + n - 1]*t[n - 1 - x]

每一对的和为定值2*n-2-x-y,然后就是求每对i+j的前缀和(所有i+j值相同按顺序加起来)

#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
const int modo = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int maxn = 1005,maxm = 1e4 + 5;
int t[maxn<<1],ans[maxn<<1][maxn<<1],n,m;

int main(){
    int x,y,_n;
    while(~RD(n)){
        _n = n;
        n = -2 + (n<<1);
        clr0(ans);
        for(int i = 0;i <= n;++i)
            RD(t[i]);
        for(int i = 0;i <= n;++i)
            for(int j = 0;j <= n;++j)
            ans[i][j] = t[i]*t[j];

        for(int i = 1;i <= n;++i)
            for(int j = 0;j < n;++j){
                ans[i][j] += ans[i-1][j+1];
            }
        RD(m);
        LL sum = 0;int res = 0;
        while(m--){
            RD2(x,y);
            x = (x+res)%_n,y = (y+res)%_n;
            int sx = _n - 1 + y,sy = _n - 1 - x;
            res = ans[sx][sy];
            if(sx - _n >= 0 && sy + _n <= n)
                res -= ans[sx-_n][sy+_n];
            sum += res;
//            cout<<x<<','<<y<<endl;
//            cout<<res<<endl;
        }
        printf("%I64d\n",sum);
    }
    return 0;
}
时间: 2024-08-01 05:37:00

hdu 5084 前缀和预处理的相关文章

HDU 5550 - Game Rooms(DP + 前缀和预处理)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=5550 题意: 一个大楼有n(2≤n≤4000)层,每层可以建一个乒乓球房或者一个游泳房,且每种房间在大楼里至少要有一个.已知每层有ti个乒乓球运动员和pi个游泳运动员(1≤ti,pi≤1e9).问怎样建房,才能使得所有运动员到相应房间的总距离最小,输出最小值. 分析: 因为每种房间在大楼里至少要有一个,所以肯定会有这样一种状态:第i层是一种房间,第i+1层是另一种房间.所以可以设d[i][x]:第i层

hdu 5317 合数分解+预处理

RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2818    Accepted Submission(s): 1108 Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and m

HDU 5317 RGCDQ (素因子分解+预处理)

题目链接:传送门 题意: 求区间[l,r]所有数的素因子的种类的最大的最大公约数...额,不知道怎么描述了... 比如说区间内的所有数的素因子种类分别为1,2,3,4,5,6,7那么结果就是gcd(3,6) 分析: 数据的范围是1~1000000,因子数最大为7,我们首先要预处理出所有数的数的因子数,但是因为 数据的范围比较大我们不能直接暴力求结果,因为因子数的可能取值比较小,因此我们可以预处 理出每种取值数的前缀和,然后就可以在O(1)的的时间内求出区间内每种取值的数. 代码如下: #incl

HDU 3944-DP?(Lucas定理+预处理)

题目地址:HDU 3944 题意:告诉你在一个在杨辉三角中的点(第n行m列),问你从(0,0)点走到该点经过的点最少的权值和(只能向下走或斜着走).同时对素数p取余 思路:根据已知的那个点(n,m),如果 n/2 >= m ,那么从已知点出发,可以一直往斜的方向走,直到边界,那么 权值和就为 C(n,m)+C(n-1,m-1)--. 然后由组合数的公式两两合并可以得到 C(n+1,m)+(n-m);如果n/2< m,那么就是一直往上走,权值和就为C(n,m)+C(n-1,m)+C(n-2,m)

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; ManacherK - Count the string HDU - 3336(前缀数量问题)

K - Count the string HDU - 3336 题目链接:https://vjudge.net/contest/70325#problem/K 题目: It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of t

hdu 5163(前缀和+分类讨论)

Taking Bus Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1275    Accepted Submission(s): 420 Problem Description Bestland has a very long road and there are n bus station along the road, whic

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]

HDU 4284 Travel Folyd预处理+dfs暴搜

题意:给你一些N个点,M条边,走每条边要花费金钱,然后给出其中必须访问的点,在这些点可以打工,但是需要先拿到证书,只可以打一次,也可以选择不打工之直接经过它.一个人从1号点出发,给出初始金钱,问你能不能访问所以的点,并且获得所以证书. 题解:目标是那些一定要访问的点,怎么到达的我们不关心,但是我们关系花费最少的路径,而且到达那个点后是一定要打工的,如果只是经过,那么在求花费最少的路径的时候已经考虑过了. 因此先用Folyd求出各个点直接的最短路径,由于N很小,又只要求出一个解,所以直接dfs暴搜

【搜索】 HDU 3533 Escape BFS 预处理

要从0,0 点 跑到m,n点  路上会有k个堡垒发射子弹,有子弹的地方不能走,子弹打到别的堡垒就会消失,或者一直飞出边界(人不能经过堡垒 可以上下左右或者站着不动 每步都需要消耗能量  一共有eng个能量 先预处理出地图 用三维数组表示mp[x][y][time] time表示该时间的地图上储存不能走的点 然后就是普通BFS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <s