問題描述
共有m部電影,編號為1~m,第i部電影的好看值為w[i]。輸入格式在n天之中(從1~n編號)每天會放映一部電影,第i天放映的是第f[i]部。
你可以選擇l,r(1<=l<=r<=n),並**第l,l+1,…,r天內所有的電影。如果同一部電影你**多於一次,你會感到無聊,於是無法獲得這部電影的好看值。所以你希望最大化**且僅**過一次的電影的好看值的總和。
第一行兩個整數n,m(1<=m<=n<=1000000)。
第二行包含n個整數f[1],f[2],…,fn。
第三行包含m個整數w[1],w[2],…,wm。
輸出格式
輸出**且僅**過一次的電影的好看值的總和的最大值。
樣例輸入
9 4
2 3 1 1 4 1 2 4 1
5 3 6 6
樣例輸出
提示樣例解釋:
**第2,3,4,5,6,7天內放映的電影,其中看且僅看過一次的電影的編號為2,3,4。
依次討論點,考慮其影響範圍,為next[i]+1~i,將此區間加上其觀賞值,再將next[next[i]]+1~next[i]減去觀賞值,在更新此時的最大值,便是結果。
此操作便等價於討論所有區間的情況!
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define inf 1e9
#define pr cout<<
#define maxn 1000005
struct node;
node tree[maxn*8];
void bt(int p,int x,int y)
void pd(int k)
void add(int p,int x,int y,int t)
int mid=tree[p].a+tree[p].b>>1;
if(mid>=x) add(p<<1,x,y,t);
if(mid1|1,x,y,t);
tree[p].maxx=max(tree[p<<1].maxx,tree[p<<1|1].maxx);
}int ask(int p,int x,int y)
int lmax=0,rmax=0;
int mid=tree[p].a+tree[p].b>>1;
if(mid>=x) lmax=ask(p<<1,x,y);
if(mid1|1,x,y);
return max(lmax,rmax);
}int n,m;
int a[maxn],v[maxn];
int next[maxn],last[maxn],cnt;
void insert(int x,int i)
int main()
for(i=1;i<=m;i++)
int maxx=0;
for(i=1;i<=n;i++)
}cout
<}
買禮物 鍊錶 線段樹)
在賣禮物的超市中有n個櫃子,每個櫃子裡都擺放了乙個禮物,每個禮物有自己的乙個編號,第i個櫃子裡的禮物編號為ai 茶山牛想給牛牛和牛妹買相同編號的禮物,但禮物有可能在某個時刻被其他人買走,而且櫃子數量太多,因此茶山牛在某個時刻只想知道某乙個櫃子區間是否能買到兩件相同編號的禮物。具體來說,有q次操作,格...
E 買禮物(鍊錶 線段樹)
傳送門 題目大意 給出乙個序列,有以下兩種操作 解題思路 很好的一道題,之前在洛谷寫過查詢區間內是否有兩數相同是用莫隊維護的區間種類數,但是本題如果寫莫隊估計要tle tletl e,然後學到了這手很強的問題轉化技巧 對於區間內的每個數,我們只需要知道它右邊離他最近相同數的在哪個位置,然後判斷區間內...
51nod 1203 JZPLCM(線段樹 鍊錶)
傳送門 一道很有意思的題。題意簡述 給乙個數列,多次詢問區間的lcm lcmlc m,答案對1e9 7 1e9 7 1e9 7取模。思路 首先考慮到乙個區間的lcm lcmlc m就是其中所有出現過的素數的最大冪的乘積。因此想到分開維護每乙個素數。然後由於p ap a pa對答案原本是有p ap a...