loj2850 無進製加法

2022-06-07 08:00:17 字數 2669 閱讀 3079

(似乎漏了乙個資料範圍,cf上的題面中還有$\sum l\le 3\cdot 10^$)

考慮$a_=2^}$時(不妨$k_\ge k_\ge ...\ge k_$),記$\sum_^b_$的最高位為$l_$,則有$l_=\max_^(k_+i-1)$

證明:大於等於$2^}$的$b_$至少要$i$個,因此該值即為下限;取$b_=2^-i+1}\ge 2^}$,因此一定可行

利用上面的這個結論,我們開始考慮正解

如果令$k_$表示$a_$最高的二進位制位,那麼$2^}\le a_<2^+1}$,取$a'_=2^+1}$,設此時$\sum_^b_$的最高為$l_+1$,$a_$減小$b_$不增,因此答案中$\sum_^b_$的最高位不超過$l_+1$

令$t=\min_+i=l_}i$,考慮答案($\sum_^b_$)的第$[k_,l_+1]$位(共$t+1$位),必然存在$t$位為1(每乙個1最多消除乙個$a_$,而存在$t$個$a_$最高位大於等於$k_$)

又因為$\forall 1\le i由於$[k_,l_+1]$中第$t$個1(從高到低)必然是$k_+1$位或第$k_$位(也有可能都選),判定當第$k_+1$位為0時能否刪除$a_,a_,...,a_$,對結果分類討論:

1.若可以,即最低位可以為$k_$,必然貪心選擇令第$[k_,l_]$位為1並剩下$a_-2^}$

2.若不可以,則第$[k_+1,l_+1]$位都必須填1,之後將$a_,a_,..,a_$都刪除即可

考慮如何判定,可以再次呼叫本過程(遞迴),即在判定過程中順便求出最小解(若有解,否則返回無解),因此對於第1種情況直接就可以退出,第2種仍要遞迴下去

時間複雜度很玄學,遞迴次數大概是$o(l)$的

對於每一次內部,用線段樹來維護區間最大值,具體方法如下:

1.對於$i$可以通過插入/刪除乙個數時,對之後的位置+1或-1來實現

2.對於每乙個$a_$,剩餘的一定是二進位制下的乙個字尾,那麼將所有數每乙個字尾(其實也只需要那一位上有1,否則跟上乙個字尾相同)放在一起基數排序,至多為$o(\sum l)$個數

3.對於每乙個$a_$,要維護下乙個1的位置(預處理);對於線段樹上,維護區間最大值,以及查詢第乙個最大值並將小於等於其的位置暴力插入,支援單點插入或刪除

這樣的複雜度再多乙個log,總複雜度即為$o((\sum l)\log \sum l)$

1 #include2

using

namespace

std;

3#define n 300005

4#define oo 0x3f3f3f3f

5#define l (k<<1)

6#define r (l+1)

7#define mid (l+r>>1)

8 vectorv[n];

9int n,m,la,rk[n],bit[n],nex[n],top[n],ans[n],f[n<<2],tag[n<<2

];10

char

s[n];

11bool cmp(int x,int

y)14

void upd(int k,int

x)18

void down(int

k)23

void build(int k,int l,int

r)28

build(l,l,mid);

29 build(r,mid+1

,r);

30 f[k]=max(f[l],f[r]);31}

32void update(int k,int l,int r,int x,int y,int

z)38

down(k);

39update(l,l,mid,x,y,z);

40 update(r,mid+1

,r,x,y,z);

41 f[k]=max(f[l],f[r]);42}

43void query(int k,int l,int r,int x,vector&v)

49down(k);

50query(l,l,mid,x,v);

51if (f[l]!=x)query(r,mid+1

,r,x,v);52}

53void add(int

k)57

void del(int

k)61

bool dfs(int

mx)74

if(nex[t])del(nex[t]);

75if ((lb+1

<=mx)&&(dfs(bit[t])))

79for(int i=0;i)add(v[i]);

80return0;

81}82int

main()93}

94for(int i=1;i<=n;i++)rk[i]=m+1;95

int mm=m;

96for(int i=0;i)

104}

105 build(1,1

,m);

106for(int i=1;i<=n;i++)add(top[i]);

107dfs(oo);

108bool flag=0

;109

for(int i=n+la;i>=0;i--)

110if ((flag)||(ans[i]))

114 }

view code

無源匯可行流 模板LOJ 115

自個設個源點s,匯點t,每個點 du i 入度 出度。du i 0時 加邊s i,邊權為du i du i 0時 加邊i t,邊權為 du i 設sum為所有 0的du i 的和 求s t的最大流,如果maxflow sum,則存在可行流,此時每條邊流掉的流量 它原本的下界就是實際的流量 dfs過程...

無源匯有上下界可行流 loj模板

loj模板題 思想是 如果存 在可行流 每條邊 必定至少 有下界的 流量 思想是,如果存在可行流,每條邊必定至少有下界的流量 思想是,如果 存在可行 流,每條 邊必定至 少有下界 的流量 那 麼直 接用下屆 填充邊的 流量 那麼直接用下屆填充邊的流量 那麼直接用下 屆填充邊 的流量 每 條邊 的流量...

loj 115 無源匯有上下界可行流

參考部落格 模型 乙個網路,求出乙個流,使得每條邊的流量必須 li且 hi,每個點必須滿足總流入量 總流出量 流量守恆 這個流的特點是迴圈往復,無始無終 這個演算法是有上下界網路流演算法的基礎,只要深刻理解這個演算法其他演算法也就水到渠成,因此我用大篇幅力圖將這個演算法的思想和細節闡述清楚.可行流演...