Description
Solution
请围观lhx大佬的博客(大佬写的太好了我都没有写的动力了em)
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; int n,k; int a[100010],b[100010]; ll sum[100010]; int L[100010],R[100010],t[200010]; ll dp[100010]; int tag[400010]; void downtag(int k) { tag[k<<1]=tag[k<<1|1]=tag[k]; tag[k]=0; } void modify(int k,int l,int r,int askx,int asky,int x) { if (askx>asky) return; if (askx<=l&&r<=asky) {tag[k]=x;return;} int mid=(l+r)/2; if (tag[k]) downtag(k); if (askx<=mid) modify(k<<1,l,mid,askx,asky,x); if (mid<asky) modify(k<<1|1,mid+1,r,askx,asky,x); } int query(int k,int l,int r,int x) { if (l==r) return tag[k]; int mid=(l+r)/2; if (tag[k]) downtag(k); if (mid>=x) return query(k<<1,l,mid,x); else return query(k<<1|1,mid+1,r,x); } int cnt; ll solve(int x){ int re=query(1,1,cnt,x); if (!re) return 0; return dp[re]+((long long)t[L[re]]-t[x]+k)%k; } int main() { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) { scanf("%d%d",&a[i],&b[i]); sum[i]=a[i]+sum[i-1]; if (b[i]!=1) continue; if (2*a[i]>k) {puts("-1");return 0;} } for (int i=1;i<=n;i++) { if (b[i]==1) { L[i]=(-2*sum[i-1]%k+k)%k; R[i]=(-2*sum[i]%k+k)%k; }else L[i]=0,R[i]=k-1; t[i*2-1]=L[i],t[i*2]=R[i]; } sort(t+1,t+2*n+1); cnt=unique(t+1,t+2*n+1)-t-1; for (int i=n;i;i--) { L[i]=lower_bound(t+1,t+cnt+1,L[i])-t; R[i]=lower_bound(t+1,t+cnt+1,R[i])-t; dp[i]=solve(L[i]); if (L[i]>R[i]) modify(1,1,cnt,R[i]+1,L[i]-1,i); else modify(1,1,cnt,1,L[i]-1,i),modify(1,1,cnt,R[i]+1,cnt,i); } ll ans=1e14; for (int i=1;i<=cnt;i++) ans=min(ans,solve(i)); printf("%lld",ans+2*sum[n]); }