前缀和,二分。
按时间模拟,每次二分找到应该扔掉哪些。
#include<map> #include<set> #include<ctime> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; #define ms(x,y) memset(x,y,sizeof(x)) #define rep(i,j,k) for(int i=j;i<=k;i++) #define per(i,j,k) for(int i=j;i>=k;i--) #define loop(i,j,k) for (int i=j;i!=-1;i=k[i]) #define inone(x) scanf("%d",&x) #define intwo(x,y) scanf("%d%d",&x,&y) #define inthr(x,y,z) scanf("%d%d%d",&x,&y,&z) #define infou(x,y,z,p) scanf("%d%d%d%d",&x,&y,&z,&p) #define lson x<<1,l,mid #define rson x<<1|1,mid+1,r #define mp(i,j) make_pair(i,j) #define ft first #define sd second typedef long long LL; typedef pair<int, int> pii; const int low(int x) { return x&-x; } const int INF = 0x7FFFFFFF; const int mod = 1e9 + 7; const int N = 1e5 + 10; const int M = 1e4 + 1; const double eps = 1e-10; int n,m,k; int sum[N],a[N],t[N]; int main() { while(~scanf("%d%d%d",&n,&m,&k)) { for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sum[i] = sum[i-1] + a[i]; } for(int i=1;i<=m;i++) scanf("%d",&t[i]); int top=0; int ans=0; for(int i=1;i<=m;i++) { if(top + t[i]-t[i-1]-1>=n) break; top = top + t[i]-t[i-1]-1; ans=t[i]; if(top!=0) { if(sum[top]<=k) { top=0; continue; } int L=1,R=top,res; while(L<=R) { int mid = (L+R)/2; if(sum[top]-sum[mid-1]>k) res=mid, L=mid+1; else R=mid-1; } top=res-1; } } if(top<n) ans=ans+n-top; printf("%d ",ans); } return 0; }