cf 1070C Cloud Computing(权值线段树+差分)
题意:https://codeforces.com/problemset/problem/1070/C
给你很多区间的物品,你可以在区间里花pi的钱最多买ci个,每天你必须有买k个的任务,问你这段区间走完你花的最少的钱。
思路:
看到区间就想到差分,如果给你一个数据结构可以很快的push一个东西,erase一个东西,并很快的知道买前k小的价钱,你不是就很容易做了吗
这个东西就是权值线段树,分分钟写好1A
#define IOS ios_base::sync_with_stdio(0); cin.tie(0); #include <cstdio>//sprintf islower isupper #include <cstdlib>//malloc exit strcat itoa system("cls") #include <iostream>//pair #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin); #include <bitset> //#include <map> //#include<unordered_map> #include <vector> #include <stack> #include <set> #include <string.h>//strstr substr strcat #include <string> #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9; #include <cmath> #include <deque> #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less #include <vector>//emplace_back //#include <math.h> #include <cassert> #include <iomanip> //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare) using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation //****************** clock_t __START,__END; double __TOTALTIME; void _MS(){__START=clock();} void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;} //*********************** #define rint register int #define fo(a,b,c) for(rint a=b;a<=c;++a) #define fr(a,b,c) for(rint a=b;a>=c;--a) #define mem(a,b) memset(a,b,sizeof(a)) #define pr printf #define sc scanf #define ls rt<<1 #define rs rt<<1|1 typedef pair<int,int> PII; typedef vector<int> VI; typedef unsigned long long ull; typedef long long ll; typedef double db; const db E=2.718281828; const db PI=acos(-1.0); const ll INF=(1LL<<60); const int inf=(1<<30); const db ESP=1e-9; const int mod=(int)1e9+7; const int N=(int)1e6+10; vector<vector<int> >in(N),out(N); struct node { int l,r,c,p; }a[N]; struct Tnode { ll ci,pi; }tr[N<<2]; void Build(int l,int r,int rt) { tr[rt].ci=tr[rt].pi=0; if(l==r)return; int mid=(l+r)>>1; Build(l,mid,rt<<1); Build(mid+1,r,rt<<1|1); } void update_dot(int pos,ll Ci,ll Pi,int l,int r,int rt) { tr[rt].ci+=Ci; tr[rt].pi+=Ci*Pi; if(l==r)return; int mid=(l+r)>>1; if(pos<=mid) update_dot(pos,Ci,Pi,l,mid,rt<<1); else update_dot(pos,Ci,Pi,mid+1,r,rt<<1|1); } ll Query(ll sum,int l,int r,int rt) { if(sum==0)return 0; if(l==r) { if(sum>tr[rt].ci) return tr[rt].ci*l; return sum*l; } int mid=(l+r)>>1; ll ans=0; if(sum<=tr[ls].ci) ans+=Query(sum,l,mid,ls); else ans+=Query(sum-tr[ls].ci,mid+1,r,rs)+tr[ls].pi; return ans; } void check(int pos,int l,int r,int rt){ if(l==r) { pr("%lld %lld\n",tr[rt].ci,tr[rt].pi); return ; } int mid=(l+r)>>1; if(pos<=mid) check(pos,l,mid,rt<<1); else check(pos,mid+1,r,rt<<1|1); } void C(int tot,int n){ fo(i,1,n) check(i,1,tot,1); pr("----------------------------------\n"); } int main() { int n,k,m; int top=0; sc("%d%d%d",&n,&k,&m); for(int i=1;i<=m;++i) { sc("%d%d%d%d",&a[i].l,&a[i].r,&a[i].c,&a[i].p); top=max(top,a[i].p); in[a[i].l].push_back(i); out[a[i].r+1].push_back(i); } ll ans=0; for(int i=1;i<=n;++i) { int sz=in[i].size(); for(int j=0;j<sz;++j) update_dot(a[in[i][j]].p,a[in[i][j]].c,a[in[i][j]].p,1,top,1); sz=out[i].size(); for(int j=0;j<sz;++j) update_dot(a[out[i][j]].p,-a[out[i][j]].c,a[out[i][j]].p,1,top,1); ans+=Query(k,1,top,1); // C(top,n); } pr("%lld\n",ans); return 0; } /**************************************************************************************/