CodeForces 1250C Trip to Saint Petersburg ###K

题目链接:https://codeforces.ml/contest/1250/problem/C

题意:自己任意选定一个区间 ,然后每天花费k钱,给定一些区间,如果选定的区间包含这些区间就可以获得这些

区间的利润,问如何选定区间才能使得钱最多
思路:考虑通过所有的起点和终点来 得到所有的答案

那么就考虑 枚举结束的端点, 然后通过线段树维护 起始点到枚举到的端点之间的最大值来更新 时间复杂度nlogn

具体是   假设枚举到i端点, 那么1~i 都需要加-k 代表前面的每一个点每过一天都花费的钱, 然后再找右端点的i的区间  让1~ 该区间的左端点+上 利润

这样做就相当于 每次枚举的 i 端点,都可以找到 1~i 为起点 i为终点 的区间的最大值    相当于左端点代表从左端点到i的区间的总利润

区间修改 单点查询即可

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define pb push_back
  5 const int maxn =2e5+10;
  6 const int mod=1e9+7;
  7 
  8 struct ac
  9 {
 10     int l,r;
 11     ll p;
 12 };
 13 ac a[maxn];
 14 
 15 vector<pair<int,ll>>E[maxn];
 16 
 17 struct ace
 18 {
 19     int l,r;
 20     ll max1,lazy;
 21     int pos;
 22     void update(ll v)
 23     {
 24         lazy+=v;
 25         max1+=v;
 26     }
 27 
 28 };
 29 ace tree[maxn*4];
 30 
 31 
 32 void pushup(int x)
 33 {
 34     if(tree[x<<1].max1>tree[x<<1|1].max1)
 35     {
 36         tree[x].max1=tree[x<<1].max1;
 37         tree[x].pos=tree[x<<1].pos;
 38     }
 39     else
 40     {
 41         tree[x].max1=tree[x<<1|1].max1;
 42         tree[x].pos=tree[x<<1|1].pos;
 43     }
 44 }
 45 
 46 void pushdown(int x)
 47 {
 48     ll v=tree[x].lazy;
 49     if(v)
 50     {
 51         tree[x<<1].update(v);
 52         tree[x<<1|1].update(v);
 53         tree[x].lazy=0;
 54     }
 55 }
 56 
 57 void build(int x,int l,int r)
 58 {
 59     tree[x].l=l,tree[x].r=r;
 60     if(l==r)
 61     {
 62         tree[x].pos=l;
 63     }
 64     else
 65     {
 66         int mid=(l+r)/2;
 67         build(x<<1,l,mid);
 68         build(x<<1|1,mid+1,r);
 69         //pushup(x);
 70     }
 71 }
 72 
 73 void update(int x,int l,int r,ll v)
 74 {
 75     int L=tree[x].l,R=tree[x].r;
 76     if(l<=L&&R<=r)
 77     {
 78         tree[x].update(v);
 79     }
 80     else
 81     {
 82         int mid=(L+R)/2;
 83         pushdown(x);
 84         if(l<=mid) update(x<<1,l,r,v);
 85         if(r>mid) update(x<<1|1,l,r,v);
 86         pushup(x);
 87     }
 88 }
 89 
 90 
 91 
 92 int main()
 93 {
 94     ios::sync_with_stdio(false);
 95     cin.tie(0);
 96     int n;
 97     ll k;
 98     cin>>n>>k;
 99     ll ans=0;
100     int l=-1,r=-1;
101     build(1,1,2e5);
102     for(int i=1;i<=n;i++)
103     {
104         cin>>a[i].l>>a[i].r>>a[i].p;
105         E[a[i].r].pb({a[i].l,a[i].p});
106     }
107     for(int i=1;i<=2e5;i++)
108     {
109         update(1,1,i,-k);
110         for(auto &v:E[i])
111         {
112             update(1,1,v.first,v.second);
113         }
114         if(tree[1].max1>ans)
115         {
116             ans=tree[1].max1;
117             l=tree[1].pos;
118             r=i;
119         }
120     }
121     if(ans<=0)
122     {
123         cout<<0<<'\n';
124     }
125     else
126     {
127         int cnt=0;
128         vector<int>temp;
129         for(int i=1;i<=n;i++)
130         {
131             if(l<=a[i].l&&r>=a[i].r)
132             {
133                 cnt++;
134                 temp.pb(i);
135             }
136         }
137         cout<<ans<<" "<<l<<" "<<r<<" "<<cnt<<'\n';
138         for(auto &v:temp)
139             cout<<v<<" ";
140     }
141 
142 
143 
144 
145 }
View Code

 

posted @ 2020-10-15 18:50  canwinfor  阅读(155)  评论(0)    收藏  举报