[unknown OJ] ZZH與揹包
一、題目
二、解法
一看就是折半搜尋,但是左邊要排序右邊要二分的, O ( 2 20 × q log ) O(2^{20}\times q\log) O(220×qlog)
這種題往往就是卡掉排序的複雜度,我們可以考慮用歸併排序來卡。
假設我們維護的是一個有序陣列,那麼我們加一個 v v v 的時候這個陣列就變成了兩個。一個是原來的陣列,一個是每個元素都加上了 v v v 的陣列,那麼這兩個陣列就可以用歸併,所以第一部分的複雜度變成 O ( 2 s ) O(2^s) O(2s)
第二部分其實也可以用歸併,一共有 q 2 n − s q2^{n-s} q2n−s 個詢問,每次加入一個 v v v 時可以用相同的方法歸併起來,複雜度是 O ( q 2 n − s ) O(q2^{n-s}) O(q2n−s),然後我們用一個指標就可以一次處理所有詢問。
那麼當 2 s = q 2 40 2^s=\sqrt{q2^{40}} 2s=q240 時最優,時間複雜度是 O ( q 2 40 ) O(\sqrt{q2^{40}}) O(q240),為了卡空間我幹了一些好事
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int M = (1<<25)+5;
const int K = 1e14;
const int K2 = 1e18;
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,k,q,o,a[M],b[M],c[M],p[M],v[45],ans[505];
struct node
{
int x,id,fl;
node(int X=0,int I=0,int F=0) : x(X) , id(I) , fl(F) {}
bool operator < (const node &b)
{
return x<b.x;
}
}s[1005];
void merge(int *a,int *b,int &m1,int m2)
{
int i=1,j=1,t=0;
while(i<=m1 && j<=m2)
{
if(a[i]%K<=b[j]%K) c[++t]=a[i],i++;
else c[++t]=b[j],j++;
}
while(i<=m1) c[++t]=a[i],i++;
while(j<=m2) c[++t]=b[j],j++;
m1=t;
for(int i=1;i<=m1;i++)
a[i]=c[i];
}
signed main()
{
n=read();q=o=read();
k=min(25ll,n);
for(int i=1;i<=n;i++)
v[i]=read();
a[++m]=0;
for(int i=1;i<=k;i++)
{
for(int j=1;j<=m;j++)
b[j]=a[j]+v[i];
merge(a,b,m,m);
}
for(int i=1;i<=q;i++)
{
int l=read()-1,r=read();
s[2*i-1]=node(l,i,K2);
s[2*i]=node(r,i,0);
}
q=q<<1;
sort(s+1,s+1+q);
for(int i=1;i<=q;i++)
p[i]=s[i].x+K*s[i].id+s[i].fl;
for(int i=k+1;i<=n;i++)
{
int t=0;
for(int j=1;j<=q;j++)
if((p[j]%K)-v[i]>=0)
b[++t]=p[j]-v[i];
merge(p,b,q,t);
}
for(int i=1,j=1;i<=q;i++)
{
while(j<=m && (p[i]%K)>=a[j]) j++;
int id=(p[i]%K2)/K,tg=p[i]/K2;
if(tg) ans[id]-=(j-1);
else ans[id]+=(j-1);
}
for(int i=1;i<=o;i++)
printf("%lld\n",ans[i]);
}
相關文章
- 揹包問題(01揹包與完全揹包)
- 01揹包、完全揹包、多重揹包詳解
- 揹包DP——完全揹包
- 揹包DP——混合揹包
- 分組揹包、完全揹包
- 【模板】01揹包、完全揹包
- 揹包
- 01揹包、有依賴的揹包
- 【BZOJ 5003】與鏈 (多重揹包 dp)
- javascript演算法基礎之01揹包,完全揹包,多重揹包實現JavaScript演算法
- 01 揹包
- 揹包DP
- 01揹包和完全揹包問題解法模板
- hdu3591The trouble of Xiaoqian 多重揹包+全然揹包
- 揹包問題
- 01揹包問題
- dp-完全揹包
- 通天之分組揹包
- 01 揹包問題
- 揹包九講(部分)
- 【例9.14】混合揹包
- POJ 2184 (01揹包)
- 51nod 1597 有限揹包計數問題 (揹包 分塊)
- 揹包 學習筆記筆記
- 揹包題型總結
- 揹包問題大合集
- 01 揹包的變形
- 經典揹包問題
- 005多重揹包問題||
- 部分揹包問題(挖
- 揹包九講問題
- 從【零錢兌換】問題看01揹包和完全揹包問題
- 動態規劃-揹包01問題推理與實踐動態規劃
- swust oj 249 求凸包面積板子
- 2. 01揹包問題
- 【leetcode】揹包問題彙總LeetCode
- 揹包問題的遞迴與非遞迴演算法遞迴演算法
- 用“揹包”去理解Go語言中的閉包Go