#include<bits/stdc++.h> using namespace std; int n,m; int a[200050],b[200050],c[200050]; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>n>>m; int d; for(int i=1;i<=n;i++){ cin>>d; if(d==1)a[i]++; if(d==2)b[i]++; if(d==3)c[i]++; a[i]+=a[i-1]; b[i]+=b[i-1]; c[i]+=c[i-1]; } int l,r; for(int i=1;i<=m;i++){ cin>>l>>r; cout<<a[r]-a[l-1]<<" "; cout<<b[r]-b[l-1]<<" "; cout<<c[r]-c[l-1]<<endl; } return 0; }
P5638 [CSGRound2] 光骓者的荣耀
题目大意
有n-1个变量,存着n个城市之间的距离,可以使用传送跳过k段路,问我们最短要走多少路
题解
依旧是经典的前缀和,我们只需要将总路程存在前缀和里,然后挨个位置向后遍历即可,直接上代码
代码
```c++ #include<bits/stdc++.h> using namespace std; long long n,k,a[1000010],minx,ji,shi; int main() { cin>>n>>k; for(int i=1;i<n;i++) { cin>>a[i]; shi+=a[i]; } if(k>0) for(int i=1;i<=n-k;i++) { if(i==1) for(int j=i;j<i+k;j++) ji+=a[j]; else { ji-=a[i-1]; ji+=a[i+k-1]; } if(ji>minx) minx=ji; } cout<<shi-minx<<endl; }
```
不要忘了开long long ^-^
P8218 【深进1.例1】求区间和
题目大意
给我们大小为n的数组a,然后进行m次查询,分别求区间(l,r)的和
思路
这也是我们的例题,讲课时讲了,这里直接上题解了
代码
#include<bits/stdc++.h> using namespace std; int n; int a[100050]; int pre[100050]; int m,l,r; int main() { cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; pre[i]=a[i]+pre[i-1]; } cin>>m; for(int i=1;i<=m;i++){ cin>>l>>r; cout<<pre[r]-pre[l-1]<<endl; } return 0; }
P1719 最大加权矩形
题目大意
有n*n的矩阵,求其中加和最大的子矩阵
思路
这题同样是例题,也直接贴代码了
代码
#include<iostream> #include<climits> #define MAXN 130 #define LL long long using namespace std; LL a[MAXN][MAXN]; LL s[MAXN][MAXN]; int main() { int N; cin>>N; for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) { cin>>a[i][j]; s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]; } LL ans=INT_MIN; for(int x1=1;x1<=N;x1++) for(int y1=1;y1<=N;y1++) for(int x2=x1;x2<=N;x2++) for(int y2=y1;y2<=N;y2++) ans=max(ans,s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]); cout<<ans; return 0; }
#include<bits/stdc++.h> using namespace std; int m; int sum[1000005]; int main() { cin>>m; for(int i=1;i<=1000000;i++)sum[i]=sum[i-1]+i; for(int i=1;i<=m/2+1;i++) { for(int j=i;j>=1;j--) { if(sum[i]-sum[j-1]>m)break; if(sum[i]-sum[j-1]==m&&i!=j)printf("%d %d\n",j,i); } } return 0; }
P1387 最大正方形
题目大意
给我们n*m的只由0和1组成的矩形,求最大不包含0的正方形的边长
思路
这道题和我们讲的那道二维前缀和的题简直一模一样,同学们可以去听下回放,这里我们就直接贴代码了
代码
#include<bits/stdc++.h> using namespace std; int n,m; int a[110][110],pre[110][110]; int main() { cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>a[i][j]; pre[i][j]=pre[i-1][j]+pre[i][j-1]+a[i][j]-pre[i-1][j-1]; } } int maax=-1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ for(int ii=i;ii<=n;ii++){ for(int jj=j;jj<=m;jj++){ if(ii-i==jj-j) if((pre[ii][jj]+pre[i-1][j-1]-pre[i-1][jj]-pre[ii][j-1])==(ii-i+1)*(jj-j+1)) if(ii-i+1>maax)maax=ii-i+1; } } } } cout<<maax<<endl; return 0; }
P6568 [NOI Online #3 提高组] 水壶
题目大意
有大小为n的数组a,求其中长度小于等于k的最大子段和
思路
弱化版最大子段和,无需多言,上代码
代码
#include<bits/stdc++.h> using namespace std; long long n,k,a[3000000],b[3000000],ans=-1; int main() { cin>>n>>k; for(int i=1;i<=n;i++){ cin>>a[i]; b[i]=b[i-1]+a[i]; } for(int i=1;i<=n-k;i++)ans=max(ans,b[i+k]-b[i-1]); cout<<ans<<endl; return 0; }
B4005 [GESP202406 四级] 黑白方块
题目大意
有n*m的网格,格子里只可能是1或0,求包含相同个数的0,1的最大矩阵
思路
和之前的最大正方形一摸一样,只不过这次判定条件是x*y/2=sum,上代码
代码
#include<bits/stdc++.h> using namespace std; int n, m; char s; int a[20][20]; int b[20][20]; int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> s; a[i][j] = (s == '1') ? 1 : 0; b[i][j] = a[i][j] + b[i-1][j] + b[i][j-1] - b[i-1][j-1]; } } int maxx = 0; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) for (int ii = i; ii <= n; ii++) for (int jj = j; jj <= m; jj++) { int black = b[ii][jj] - b[i-1][jj] - b[ii][j-1] + b[i-1][j-1]; int area = (ii - i + 1) * (jj - j + 1); if (area % 2 == 0 && black == area / 2) if (area > maxx) maxx = area; } cout << maxx << endl; return 0; }
B4192 [海淀区小学组 2023] 分数线
题目大意
给了长度为n的数组a,要求从某一位置分成两段,且这两段总和都在x和y之间
思路
直接前缀和,然后遍历一遍分别判断即可
代码
```c++ #include<bits/stdc++.h> using namespace std; const int N=100001; long long m,c[N]; long long d[N],x,y; int main(){ cin>>m; for(int i=1;i<=m;i++){ cin>>c[i]; d[i]=c[i]+d[i-1]; } cin>>x>>y; for(int i=1;i<=m;i++){ int n2=d[i-1],n1=d[m]-d[i-1]; if(n1>=x&&n1<=y&&n2>=x&&n2<=y){ cout<<i<<"\n"; return 0; } } cout<<"0\n"; return 0; }