题解 P7140 【[THUPC2021 初赛]区间矩阵乘法】
题意清晰思路简单码量少好评,卡常一万年 -9 差评。
成为了相同题目数量下罚时(可能)最长的队伍,顺便水一水题解。
似乎是目前的最优解,但估计马上就不是了(
题意很简单就是给一个序列, 每次询问给出
(第一遍看成了
首先是发现
然后维护一个前缀和
然后做到这里发现很难再继续化简,爬回去重新读题,发现询问保证
这样的话,当
所以维护一个
意义通俗一点说就是,从
显然,这个
这样的话这个式子继续化简,发现只有
然后用维护的
这样单次询问直接暴力枚举
#include <bits/stdc++.h>
#define rgi register int
using namespace std;
namespace IO{
#define getchar() (P1_==P2_&&(P2_=(P1_=Ibuf)+fread(Ibuf,1,1<<21,stdin),P1_==P2_)?EOF:*P1_++)
#define putchar(c) (O-Obuf<8388608)?(*O++=c):(fwrite(Obuf,O-Obuf,1,stdout),O=Obuf,*O++=c)
char Ibuf[8388608],*P1_=Ibuf,*P2_=Ibuf,Obuf[8388608],*O=Obuf;
int f,ch,Onum[32],Ohd;long long K_;
template<typename T>inline void read(T&x){
x=f=ch=0;while(!isdigit(ch))f|=(ch=='-'),ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
f&&(x=-x);
}
template<typename T>inline void write(T x){
if(x==0)return putchar('0'),void();
if(x<0)putchar('-'),x=-x;
while(x>0)K_=x/10,Onum[++Ohd]=(x-(K_<<1)-(K_<<3))^'0',x=K_;
while(Ohd>0)putchar(Onum[Ohd]),--Ohd;
}
inline void _Exit0(){
fwrite(Obuf,O-Obuf,1,stdout),exit(0);
}
}using namespace IO;
int Block,n,m,p1,p2,d;
unsigned int a[200010],ans;
unsigned int s[450][200010],sum[200010];
int main(){
read(n),Block=sqrt(n);
for(rgi i=1;i<=n;++i)read(a[i]),sum[i]=sum[i-1]+a[i];
for(rgi i=1;i<=Block;++i){
for(rgi j=1;j<=i;++j)s[i][j]=a[j];
for(rgi j=i+1;j<=n;++j)s[i][j]=s[i][j-i]+a[j];
}
read(m);
for(rgi t=1;t<=m;++t){
read(d),read(p1),read(p2),ans=0;
for(rgi j=0;j<d;++j)ans+=(s[d][p1+(d-1)*d+j]-s[d][p1+j]+a[p1+j])*(sum[p2+d*(j+1)-1]-sum[p2+d*j-1]);
write(ans),putchar('\n');
}
_Exit0();
}