题目链接: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 #include2 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 ) 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 ) 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 ) 86 { 87 add[i]+=val; 88 } 89 } 90 signed main() 91 { 92 // cout< 93 scanf("%lld %lld",&n,&m); 94 for(ll i=1; 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 })
线段树代码:
1 #include2 using namespace std; 3 # define ll long long 4 # define lson l,m,rt<<1 5 # define rson m,r,rt<<1|1 6 const ll inf =0x3f3f3f3f3f3f3f; 7 const int maxn= 3e6+100; 8 struct node 9 { 10 ll st; 11 ll ed; 12 bool friend operator < (node t1,node t2) 13 { 14 return t1.ed<t2.ed; 15 } 16 } q[maxn]; 17 ll tree[maxn<<2],lazy[maxn<<2]; 18 void up(ll rt) 19 { 20 tree[rt]=min(tree[rt<<1],tree[rt<<1|1]); 21 } 22 void down(int rt) 23 { 24 tree[rt<<1]+=lazy[rt]; 25 tree[rt<<1|1]+=lazy[rt]; 26 lazy[rt<<1]+=lazy[rt]; 27 lazy[rt<<1|1]+=lazy[rt]; 28 lazy[rt]=0; 29 } 30 void build(ll l,ll r,ll rt) 31 { 32 if(l+1==r) 33 { 34 scanf("%lld",&tree[rt]); 35 return ; 36 } 37 ll m=(l+r)>>1; 38 build(lson); 39 build(rson); 40 up(rt); 41 } 42 ll ask(ll L,ll R,ll l, ll r,ll rt) 43 { 44 if(R<=l||L>=r) 45 return inf ; 46 if(L<=l&&R>=r) 47 { 48 return tree[rt]; 49 } 50 ll m=(l+r)>>1ll; 51 down(rt); 52 return min(ask(L,R,lson),ask(L,R,rson)); 53 } 54 void update(ll L,ll R,ll l,ll r,ll rt,ll val) 55 { 56 if(R<=l||L>=r) 57 return ; 58 if(L<=l&&R>=r) 59 { 60 tree[rt]+=val; 61 lazy[rt]+=val; 62 return ; 63 } 64 ll m=(l+r)>>1; 65 down(rt); 66 update(L,R,lson,val); 67 update(L,R,rson,val); 68 up(rt); 69 } 70 int main() 71 { 72 ll n,m; 73 // cout< 74 scanf("%lld %lld",&n,&m); 75 build(1,n,1); 76 ll st,ed; 77 for(ll i=1; i<=m; i++) 78 { 79 scanf("%lld %lld",&q[i].st,&q[i].ed); 80 q[i].st++; 81 q[i].ed++; 82 if (q[i].st > q[i].ed) 83 swap(q[i].st, q[i].ed); 84 } 85 sort(q+1,q+m+1); 86 ll sum=0; 87 for(ll i=1; i<=m; i++) 88 { 89 ll minn; 90 minn=ask(q[i].st,q[i].ed,1,n,1); 91 sum+=minn; 92 update(q[i].st,q[i].ed,1,n,1,-minn); 93 } 94 printf("%lld\n",sum); 95 return 0; 96 }