[unknown OJ] ZZH與揹包

C202044zxy發表於2020-12-02

一、題目

點此看題

二、解法

一看就是折半搜尋,但是左邊要排序右邊要二分的, 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} q2ns 個詢問,每次加入一個 v v v 時可以用相同的方法歸併起來,複雜度是 O ( q 2 n − s ) O(q2^{n-s}) O(q2ns),然後我們用一個指標就可以一次處理所有詢問。

那麼當 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]);
}

相關文章