1. 程式人生 > >2018-2019 ICPC, NEERC, Southern Subregional Contest C - Cloud Computing [contest/1070]

2018-2019 ICPC, NEERC, Southern Subregional Contest C - Cloud Computing [contest/1070]

C - Cloud Computing [contest/1070]

題面

在這裡插入圖片描述

思路

考慮維護一個 c [ i ] c[i] 的權值線段樹,並在樹上維護

c [ i ] \sum c[i] , p [ i ]
p[i]
,在到達區間左端點時,加入線段樹,到達右端點後刪除掉,在樹內二分 c [ i ] \sum c[i]
即可

程式碼

(隊友的程式碼 貼上來了)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long LL;
#define mp make_pair
#define se second
#define fi first
#define Son int mid=l+r>>1,lson=x<<1,rson=x<<1|1
const int maxn = 1e6+10;
const int mod = 1e9+7;
vector<pair<int,int> > ad[maxn],de[maxn];
struct nod {
    LL sum,num;
}tree[maxn<<2];
void up(int x,int l,int r,int pos,int v) {
    if (l==r) {
        tree[x].num+=v;
        tree[x].sum+=1ll*l*v;
        return ;
    }
    Son;
    if (pos<=mid) up (lson,l,mid,pos,v);
    else up (rson,mid+1,r,pos,v);
    tree[x].sum=tree[lson].sum+tree[rson].sum;
    tree[x].num=tree[lson].num+tree[rson].num;
}
ll query(int x,int l,int r,ll re) {
    if (tree[x].num<=re) {
        return tree[x].sum;
    }
    if (l==r) {
        return re*l;
    }
    Son;
    if (tree[lson].num>=re) return query(lson,l,mid,re);
    else return tree[lson].sum+query(rson,mid+1,r,re-tree[lson].num);
}
int main(){
    int n,k,m;
    scanf("%d%d%d",&n,&k,&m);
    int h=0;
    ll ans=0;
    for (int i=1;i<=m;i++) {
        int l,r,c,p;
        scanf("%d%d%d%d",&l,&r,&c,&p);
        if (p>h) h=p;
        ad[l].push_back(mp(c,p));
        de[r+1].push_back(mp(c,p));
    }
    for (int i=1;i<=n;i++) {
        for (int j=0;j<ad[i].size();j++) {
            up(1,1,h,ad[i][j].se,ad[i][j].fi);
        }
        for (int j=0;j<de[i].size();j++) {
            up(1,1,h,de[i][j].se,-de[i][j].fi);
        }
        ans+=query(1,1,h,k);
    }
    printf("%lld\n",ans);
}