//795 前缀和
#include<bits/stdc++.h>
using namespace std;
//795 前缀和
const int N=1e5+10;
int n,m;
int a[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i],a[i]+=a[i-1];
for(int i=0;i<m;i++)
{
int l,r;
cin>>l>>r;
cout<<a[r]-a[l-1]<<endl;
}
return 0;
}
//796子矩阵的和
#include<bits/stdc++.h>
using namespace std;
//796 子矩阵的和
const int N=1e3+10;
int f[N][N];
int m,n,q;
int main()
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>f[i][j];
f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
cout<<i<<" "<<j<<"为"<<f[i][j]<<endl;
}
}
for(int i=0;i<q;i++)
{
int x1,x2,y1,y2;
cin>>x1>>y1>>x2>>y2;
int t=f[x2][y2]-f[x1-1][y2]-f[x2][y1-1]+f[x1-1][y1-1];
cout<<t<<endl;
}
return 0;
}
//1230 K倍空间
自己的暴力做法超时了
#include<bits/stdc++.h>
using namespace std;
//1230 K倍空间
typedef long long LL;
const int N=1e5+10;
int n,k;
LL a[N];
int main()
{
cin>>n>>k;
int cnt=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]+=a[i-1];
if(a[i]%k==0)cnt++;
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if((a[j]-a[i])%k==0)cnt++;
}
}
cout<<cnt<<endl;
}
y解法:
两个数关于k同余,说明两个数构成的区间的数之和可以被k整除。
但是如果第三个数出现了,那么就会各自与前面的所有同余的数配成一对,所以每次先在ans上加上前面所有同余的数,然后再给数组++。
还要注意的是由于从1开始遍历,可能存在某个si可以整除k,而这个左端点就是s0,,所以我们呢要先初始化这个b[0]=1;也就是相当于前面存在一个可以整除k的数0。
#include<bits/stdc++.h>
using namespace std;
//1230 K倍空间 y做法
typedef long long LL;
const int N=1e5+10;
int n,k;
//大数组一定要放到外面
LL b[N];//用来记录已经出现的同一个某余数的个数
LL a[N];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
a[i]+=a[i-1];
}
LL ans=0;
b[0]=1;
for(int i=1;i<=n;i++)
{
ans+=b[a[i]%k];
b[a[i]%k]++;
}
printf("%lld",ans);
}