半期考试要来了 一周没有做题
本来就欠账的我现在欠了更多账hh
1.P10903 [蓝桥杯 2024 省 C] 商品库存管理
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=300010;
int arr[N]={0},ze[N],on[N],l[N],r[N],cf[N];
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
l[i]=a;r[i]=b;
cf[l[i]-1]++;cf[r[i]]--;
}
for(int i=1;i<=n;i++){
arr[i]=arr[i-1]+cf[i-1];//这个商品有几个
if(arr[i]==0){
ze[i]++;
}
if(arr[i]==1){
on[i]++;
}
}
for(int i=1;i<=n;i++){
ze[i]+=ze[i-1];//最后数组里前i商品中个0的总和
on[i]+=on[i-1];//最后数组里前i商品中个1的总和
}
for(int i=1;i<=m;i++){
cout<<ze[l[i]-1]+on[r[i]]-on[l[i]-1]+ze[n]-ze[r[i]];
if(i!=m){
cout<<endl;
}
}
}
//区间外的0+区间内的1就是答案
//前缀和是求出i之前0/1的个数
我的代码确实一般 但是是我这个弱鸡自己想的TT
思路:
对于每一段题目给出的区间:在完成所有操作的数组中 区间外的0的个数+区间内的1的个数就是答案 因为区间内如果是1的话 在你不执行这一次操作的时候 区间内的1就会变成0
1.arr[N]={0} 完成所有操作的数组 每个arr[i]体现第i种商品的个数
2.ze[N] 前i种商品的0的总个数
3.on[N] 前i种商品的1的总个数
4.l[N],r[N] 每次操作的左区间和右区间
5.cf[N] 用来储存差分操作 但是其实整个代码我一直用的都是前缀和
6.前缀和数组的好处就是你可以每次不必遍历所有数据,前缀和数组内的每一项都代表一种“情况”
7.由题意可知这道题的结果只和0/1有关 其他的数字不用管 我的方法是先统计每个商品是不是0/1(是的话就是1),然后再前缀和求出前i个商品有多少0/1
8.最后的输出 要注意答案的区间是[l,r]是闭区间,所以答案是1到l-1之间的0个数加上l到r之间的1个数加上r+1到n的0个数 这里举例r+1到n的0个数怎么求:1到n的0的个数减去1到r的0的个数