NC53274. 两道料理
描述
输入描述
从标准输入中读取数据。
第一行两个整数N,M。
接下来N行,每行三个整数。
接下来M行,每行三个整数。
输出描述
输出数据到标准输出中。
一个整数,表示比太郎能得到的最高艺术感评分。
示例1
输入:
4 3 2 1 1 3 8 1 2 13 1 1 13 1 3 6 1 2 11 1 2 15 1
输出:
6
说明:
比太郎可以按照此方案进行烹饪:示例2
输入:
5 7 16 73 16 17 73 10 20 73 1 14 73 16 18 73 10 3 73 2 10 73 7 16 73 19 12 73 4 15 73 15 20 73 14 15 73 8
输出:
63
说明:
这组样例满足子任务1的限制。示例3
输入:
9 11 86 565 58 41 469 -95 73 679 28 91 585 -78 17 513 -63 48 878 -66 66 901 59 72 983 -70 68 1432 11 42 386 -87 36 895 57 100 164 10 96 812 -6 23 961 -66 54 193 51 37 709 82 62 148 -36 28 853 22 15 44 53 77 660 -19
输出:
99
C++(clang++11) 解法, 执行用时: 3852ms, 内存消耗: 125928K, 提交时间: 2021-02-07 11:55:29
#include<cstdio> #include<algorithm> #include<set> using namespace std; #define ll long long ll gi(){ ll x=0,w=1;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')w=0,ch=getchar(); while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } const int N=1e6+5; struct node{ int x,y;ll z; bool operator < (const node &b)const {return x<b.x;} }a[N<<1]; int n,m,tot,pos[N<<2]; ll A[N],S[N],P[N],B[N],T[N],Q[N],val[N],ans; set<int>Set;set<int>::iterator it; void up(int x){pos[x]=val[pos[x<<1]]<val[pos[x<<1|1]]?pos[x<<1]:pos[x<<1|1];} void build(int x,int l,int r){ if(l==r){pos[x]=l;return;}int mid=l+r>>1; build(x<<1,l,mid);build(x<<1|1,mid+1,r);up(x); } void modify(int x,int l,int r,int p,ll v){ if(l==r){ val[l]+=v; if(val[l])Set.insert(l);else Set.erase(l); return; } int mid=l+r>>1;p<=mid?modify(x<<1,l,mid,p,v):modify(x<<1|1,mid+1,r,p,v);up(x); } int main(){ n=gi();m=gi(); for(int i=1;i<=n;++i)A[i]=A[i-1]+gi(),S[i]=gi(),P[i]=gi(); for(int i=1;i<=m;++i)B[i]=B[i-1]+gi(),T[i]=gi(),Q[i]=gi(); for(int i=1;i<=n;++i) if(A[i]<=S[i]){ ans+=P[i];int p=upper_bound(B+1,B+m+1,S[i]-A[i])-B; if(p<=m)a[++tot]=(node){i-1,p,-P[i]}; } for(int i=1;i<=m;++i) if(B[i]<=T[i]){ int p=upper_bound(A+1,A+n+1,T[i]-B[i])-A-1; a[++tot]=(node){p,i,Q[i]}; } a[++tot]=(node){n,1,0}; sort(a+1,a+tot+1);build(1,1,m); for(int i=1,j=1;i<=tot;i=j=j+1){ while(j<tot&&a[j+1].x==a[i].x)++j; if(a[i].x==n){ for(int k=i;k<=j;++k)ans+=a[k].z; for(int x:Set)ans+=val[x]; printf("%lld\n",ans); return 0; } for(int k=i;k<=j;++k)modify(1,1,m,a[k].y,a[k].z); while(val[pos[1]]<0){ int p=pos[1];ll v=val[p]; it=Set.find(p);++it; if(it!=Set.end())modify(1,1,m,*it,v); modify(1,1,m,p,-v); } } }