HDU 6336 找规律 容斥

通过观察可以发现,假设给的数组长度为l,如果l为奇数,那么ll的矩阵周期性出现,如果l为偶数,那么2l2l的方阵周期性出现,所以我们可以把2l * 2l的方阵存起来,然后写一个函数f,这个函数接受一个点,返回这个点与0,0点所代表的方阵中所有子元素的和,接下来只要运用容斥关系,把四个点扔进这个函数求值即可。

#include <iostream>
#include <math.h>
#include <iomanip>
#include <string>
#include <cstdio>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
#define N 17
#define M 998244353
#define ll long long
using namespace std;
ll A[10];
ll map[42][42];
ll t,l,q;
ll cnt;
ll pre[21][21];
ll g[21];

ll sum(ll x,ll y){
    if(x == 0 || y == 0){
        return 0;
    }
    for(int i=1;i<=2*l;i++){
        g[i] = g[i-1] + pre[i][2*l] * (y/(2*l)) + pre[i][y%(2*l)];
    }
    return g[2*l] * (x/(2*l)) + g[x%(2*l)];
}


int main() {
    ll i,j;
    scanf("%lld",&t);
    while (t > 0)
    {
        t--;
        ll x1,y1,x2,y2;
        scanf("%lld",&l);
        for(i=0;i<l;i++){
            scanf("%lld",&A[i]);//从0开始
        }
        cnt = -1;
        for(i = 1;i<= 4*l;i++){
            for(j=1;j<=i;j++){
                cnt = (cnt+1)%l;
                map[j][i+1-j] = A[cnt];
            }
        }
        for(i=1;i<=2*l;i++){
            for(j=1;j<=2*l;j++){
                pre[i][j] = pre[i][j-1] + map[i][j];
            }
        }
        scanf("%lld",&q);
        for(i=1;i<=q;i++){
            scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
            //cout<<sum(x1-1,y1-1)<<endl;
            //cout<<sum(x2,y2)<<endl;
            y1++,x1++,y2++,x2++;
            ll ans = sum(x1-1,y1-1) + sum(x2,y2) - sum(x2,y1-1) - sum(x1-1,y2);
            printf("%lld\n",ans);
        }
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值