題解 lg2605 基站選址

2022-03-06 12:53:19 字數 1664 閱讀 5205

題面

設 \(f[i,j]\) 表示前 i 個村莊建立 j 個基站,且第 i 個村莊有基站的最小花費

則有 \(f[i,j]=min_\\) 其中 \(cost(k,i)\) 表示第 i ,k 個村莊建有基站,中間沒有,所需要補償的費用

發現轉移式中從 j-1 -> j ,我們可以脫去 j 這一維

考慮怎麼計算 \(cost(k,i),k< i\) 。如果村莊 \(a\) 產生補償費,當且僅當它沒有被覆蓋到,那麼我們可以預處理出 **能夠覆蓋到 \(a\) 的最小和最大的村莊 \(st_a\)

\(ed_a\) ** ,當 \(i\) 覆蓋不到 \(a\) ,也即\(i>ed_a\) 的時候,就把從 1 到 \(st_a-1\) 的村莊的 \(cost\) 都加上 \(w_a\)

我們要支援乙個區間加的操作,和乙個區間取最小值的操作。可用線段樹維護\(f+cost\) 來實現

#includeusing namespace std;

#define int long long

int const maxn=400000,inf=0x7fffffffffff;

int n,k,d[maxn],c[maxn],s[maxn],w[maxn],st[maxn],ed[maxn];

int tot,h[maxn],f[maxn],ans;

struct edgee[maxn];

int read()

while(isdigit(c))

return x*f;

}void add(int u,int x),h[u]=tot;

}struct segment_tree

int mid=(l+r)>>1;

build(x<<1,l,mid);

build(x<<1|1,mid+1,r);

a[x]=min(a[x<<1],a[x<<1|1]);

return;

} void pushdown(int x)

return;

} void change(int x,int l,int r,int v)

pushdown(x);

int mid=(l[x]+r[x])>>1;

if(l<=mid)change(x<<1,l,r,v);

if(r>mid)change(x<<1|1,l,r,v);

a[x]=min(a[x<<1],a[x<<1|1]);

} int query(int x,int l,int r)

pushdown(x);

int mid=(l[x]+r[x])>>1;

int ans=inf;

if(l<=mid)ans=min(ans,query(x<<1,l,r));

if(r>mid)ans=min(ans,query(x<<1|1,l,r));

a[x]=min(a[x<<1],a[x<<1|1]);

return ans;

}}tree;

signed main()

n++,k++;w[n]=d[n]=inf;

for(int i=1;i<=n;i++)

} ans=min(ans,f[n]);

} printf("%lld\n",ans);

return 0;

}

LG4948 題解報告

p4948 題解報告 求 sum 的值,其中 n le10 k le 2 times 10 3,a le 10 9 本題在 具體數學 一書中有詳細的解法思路說明,可以在該書第二章 和式 中得到思路的啟發。對這個式子進行擾動。令 s k sum 當 a 1 時,有 s k sum sum i 1 k ...

題解 lg2034 選擇數字

給定一行n個非負整數a 1 a n 現在你可以選擇其中若干個數,但不能有超過k個連續的數字被選擇。你的任務是使得選出的數字的和最大。設 f i,0 表示考慮到數字 i 並選擇 i 的最大和,f i,1 表示考慮到數字 i 並選擇 i 的最大和 那麼 f i,0 min f i 1,0 f i 1,1...

題解 lg2480 古代豬文

給定整數 q,n 1 leq q,n leq 10 9 求 q c mod 999911659 首先由擴充套件尤拉定理可知,因為999911659為質數 q c equiv q c mod 999911658 mod 999911659 設 x sum c mod 999911658 然後再 由於 ...