题目链接:https://pintia.cn/problem-sets/1108203702759940096/problems/1108204121661857798
题目大意:
森森开了一家快递公司,叫森森快递。因为公司刚刚开张,所以业务路线很简单,可以认为是一条直线上的N个城市,这些城市从左到右依次从0到(编号。由于道路限制,第i号城市(,)与第(号城市中间往返的运输货物重量在同一时刻不能超过Ci公斤。
公司开张后很快接到了Q张订单,其中j张订单描述了某些指定的货物要从Sj号城市运输到Tj号城市。这里我们简单地假设所有货物都有无限货源,森森会不定时地挑选其中一部分货物进行运输。安全起见,这些货物不会在中途卸货。
为了让公司整体效益更佳,森森想知道如何安排订单的运输,能使得运输的货物重量最大且符合道路的限制?要注意的是,发货时间有可能是任何时刻,所以我们安排订单的时候,必须保证共用同一条道路的所有货车的总重量不超载。例如我们安排1号城市到4号城市以及2号城市到4号城市两张订单的运输,则这两张订单的运输同时受2-3以及3-4两条道路的限制,因为两张订单的货物可能会同时在这些道路上运输。
具体思路:首先对区间的右端点进行排序,先处理短的区间,再去处理长的区间,这样就能保证是最大了。其实就是区间查询和区间修改。
作死用分块打的区间查询和区间修改,有一个两分的样例就是A不了。。以后这种区间修改还是用线段树吧,,
分块代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const ll inf =0x3f3f3f3f3f3f3f3f; 5 const int maxn= 3e6+100; 6 ll a[maxn]; 7 struct node 8 { 9 ll st; 10 ll ed; 11 bool friend operator < (node t1,node t2) 12 { 13 return t1.ed<t2.ed; 14 } 15 } q[maxn]; 16 ll vis[maxn]; 17 ll belong[maxn]; 18 ll l[maxn],r[maxn]; 19 ll add[maxn]; 20 ll sum[maxn]; 21 ll n,m; 22 void build() 23 { 24 ll block=(ll)sqrt(n-1ll); 25 for(ll i=1; i<n; i++) 26 belong[i]=i/block+1ll; 27 ll tot=(n-1)/block; 28 if((n-1)%block) 29 tot++; 30 for(ll i=1; i<=tot; i++) 31 { 32 l[i]=(i-1)*block+1ll; 33 r[i]=(i)*block; 34 } 35 r[tot]=n-1; 36 for(ll i=1; i<=tot; i++) 37 { 38 sum[i]=inf; 39 for(ll j=l[i]; j<=r[i]; j++) 40 { 41 sum[i]=min(vis[j],sum[i]); 42 } 43 } 44 } 45 ll ask(ll st,ll ed) 46 { 47 ll ans=inf; 48 if(belong[st]==belong[ed]) 49 { 50 for(ll i=st; i<=ed; i++) 51 { 52 ans=min(ans,vis[i]+add[belong[st]]); 53 } 54 return ans; 55 } 56 for(ll i=st; i<=r[belong[st]]; i++) 57 ans=min(ans,vis[i]+add[belong[st]]); 58 for(ll i=l[belong[ed]]; i<=ed; i++) 59 ans=min(ans,vis[i]+add[belong[ed]]); 60 for(ll i=belong[st]+1; i<belong[ed]; i++) 61 ans=min(ans,sum[i]+add[i]); 62 return ans; 63 } 64 void up(ll st,ll ed,ll val) 65 { 66 if(belong[st]==belong[ed]) 67 { 68 for(ll i=st; i<=ed; i++) 69 { 70 vis[i]+=val; 71 sum[belong[st]]=min(sum[belong[st]],vis[i]); 72 } 73 return ; 74 } 75 for(ll i=st; i<=r[belong[st]]; i++) 76 { 77 vis[i]+=val; 78 sum[belong[st]]=min(sum[belong[st]],vis[i]); 79 } 80 for(ll i=l[belong[ed]]; i<=ed; i++) 81 { 82 vis[i]+=val; 83 sum[belong[ed]]=min(sum[belong[ed]],vis[i]); 84 } 85 for(ll i=belong[st]+1; i<belong[ed]; i++) 86 { 87 add[i]+=val; 88 } 89 } 90 signed main() 91 { 92 // cout<<inf<<endl; 93 scanf("%lld %lld",&n,&m); 94 for(ll i=1; i<n; i++) 95 scanf("%lld",&vis[i]); 96 sort(q+1,q+m+1); 97 build(); 98 ll st,ed; 99 for(ll i=1; i<=m; i++) 100 { 101 scanf("%lld %lld",&q[i].st,&q[i].ed); 102 q[i].st++; 103 q[i].ed++; 104 if (q[i].st > q[i].ed) 105 swap(q[i].st, q[i].ed); 106 } 107 sort(q+1,q+m+1); 108 ll sum=0; 109 for(ll i=1; i<=m; i++) 110 { 111 ll minn; 112 minn=ask(q[i].st,q[i].ed-1); 113 sum+=minn; 114 up(q[i].st,q[i].ed-1,-minn); 115 } 116 printf("%lld\n",sum); 117 return 0; 118 }