日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【AGC012E】 Camel and Oases ST表+状压dp

發布時間:2023/12/14 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【AGC012E】 Camel and Oases ST表+状压dp 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目大意:一排點,兩點間有距離。?初始你有一個行走值$v$,如果相鄰兩點距離不超過$v$你可以自由在這兩點行走。?
當$v$大于$0$時,你可以選擇某一時刻突然飛到任意點,這樣做后$v$會減半(下取整)。?問從每個位置初始出發能否到達所有位置。

點的數量$≤2*10^5$,$v≤2*10^5$,$|兩點距離|≤10^9$。

?

我們令$l[i][j]$表示從$i$出發,一路往左走,經過所有長度不超過$v>>j$(此處的$>>$表示右移,以下都是)的邊,能走到最左的點的編號。

令$r[i][j]$表示從$i$出發,一路往右走,經過所有長度不超過$v>>j$的邊,能走到最右的點的編號。

令$n$表示點的數量,$m=\lceil log_2v\rceil$。

我們不難得出:從$u$號點出發,是否可以遍歷完所有點的判斷條件,可以轉化為:

是否可以將點集分成$m+1$個塊,且第$i$(從$0$到$m$)個塊內邊的長度均不超過$v>>i$,且第$u$號點需要在第$0$個塊內。

?

那么,對于$[1,2^m)$中的每一個$i$($i$是一個二進制狀態,$i$的第$j$($j$從$1$到$m$)位為$1$表示選擇了圖中第$j$個塊)

求一個最大的$f[i]$,滿足區間$[1,f[i]]$中的點能分成由狀態i表示的若干個塊。

同理,求一個最小的$g[i]$,滿足區間$[g[i],n]$中的點能分成由狀態i表示的若干個塊。

求這個可以通過l和r的值+狀壓$dp$實現,時間復雜度是$O(v\ log\ v)$。

我們令$o=2^m-2$。

我們發現,若存在$i$,使得$r[f[i]][0]>=l[g[o$^$i]][0]$,那么從區間$[\ l[g[o$^$i]][0]\ ,\ r[f[i]][0]\ ]$中出發的點,顯然可以遍歷玩所有點。

我們可以$O(1)$打上一個標記,求答案的時候$O(n)$掃一遍,判斷某個點是否被打了標記即可。

總時間復雜度:$O(n\ log\ v+v\ log\ v)$。

1 #include<bits/stdc++.h> 2 #define M 400005 3 #define YXQAK printf("Possible\n") 4 #define XFZBL printf("Impossible\n"); 5 using namespace std; 6 7 int a[M]={0},n,m,v,l[20][M]={0},r[20][M]={0}; 8 int f[M]={0},g[M]={0},p[M]={0}; 9 10 int main(){ 11 scanf("%d%d",&n,&v); 12 for(int i=1;i<=n;i++) scanf("%d",a+i); 13 sort(a+1,a+n+1); 14 for(int j=0,V=v;V;j++,V>>=1){ 15 m=max(m,j); 16 for(int i=1;i<=n;i++){ 17 int I=i+1; 18 while(I<=n&&a[I]-a[I-1]<=V) I++; 19 I--; 20 for(int ii=i;ii<=I;ii++) 21 l[j][ii]=i,r[j][ii]=I; 22 i=I; 23 } 24 } 25 m++; 26 for(int i=1;i<=n;i++) l[m][i]=r[m][i]=i; 27 for(int i=0;i<(1<<m);i++) g[i]=n; f[0]=1; 28 for(int i=1;i<(1<<m);i++){ 29 int now=1; 30 for(int j=m-1;~j;j--) 31 if((1<<j)&i) 32 f[i]=max(f[i],r[j+1][f[i^(1<<j)]]+1); 33 34 now=n; 35 for(int j=m-1;~j;j--) 36 if((1<<j)&i) 37 g[i]=min(g[i],l[j+1][g[i^(1<<j)]]-1); 38 } 39 40 for(int i=0;i<(1<<m);i++){ 41 if(r[0][f[i]]+1>=l[0][g[(1<<m)-i-1]]) 42 p[l[0][g[(1<<m)-i-1]]]++,p[r[0][f[i]]+1]--; 43 } 44 for(int i=1;i<=n;i++){ 45 p[i]+=p[i-1]; 46 if(p[i]) YXQAK; 47 else XFZBL; 48 } 49 }

轉載于:https://www.cnblogs.com/xiefengze1/p/9806354.html

總結

以上是生活随笔為你收集整理的【AGC012E】 Camel and Oases ST表+状压dp的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。