【DP】AGC012 ECamel and Oases
生活随笔
收集整理的這篇文章主要介紹了
【DP】AGC012 ECamel and Oases
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分析:
有點套路的狀壓題
很顯然,最多logV層,所以可以記錄每一層的選取狀態(第一層保證不能選)。
定義f1(mask)f1(mask)f1(mask)表示選取狀態為mask時,從最左端開始連續覆蓋的最右端。
定義f2(mask)f2(mask)f2(mask)表示選取狀態為mask時,從最右端開始連續覆蓋的最左端。
之所以要分成兩段,是因為最終我們要判斷從某一段開始,能否全部覆蓋,所以最開始一個區間類似于詢問,對每個詢問,枚舉左側的選取狀態,得到右側對應的選取狀態,然后看兩段能否覆蓋到當前這一段。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #define SF scanf #define PF printf #define MAXN 1000010 #define INF 0x3FFFFFFF using namespace std; int n,v,logv; int x[MAXN]; int f1[MAXN],f2[MAXN]; int l[22][MAXN],r[22][MAXN],cnt[22]; int find_l(int x,int pos){pos++;int now=upper_bound(l[x]+1,l[x]+1+cnt[x],pos)-l[x];now--;if(now<=0)return pos;return max(r[x][now],pos-1); } int find_r(int x,int pos){pos--;int now=lower_bound(r[x]+1,r[x]+1+cnt[x],pos)-r[x];if(now>cnt[x])return pos;return min(l[x][now],pos+1); } int ans[MAXN]; int main(){memset(f2,0x3f3f3f3f,sizeof f2);SF("%d%d",&n,&v);for(int i=1;i<=n;i++)SF("%d",&x[i]); x[0]=-INF;x[n+1]=INF;for(logv=0;(1<<logv)<=v;logv++);logv++;for(int i=0;i<logv;i++){int v1=v>>i;cnt[i]=1;l[i][cnt[i]]=1;for(int j=1;j<=n;j++)if(x[j+1]-x[j]>v1){r[i][cnt[i]]=j;cnt[i]++;l[i][cnt[i]]=j+1; }cnt[i]--;}if(cnt[0]>logv){for(int i=1;i<=n;i++)PF("Impossible\n");return 0; }f1[0]=0;f2[0]=n+1;for(int mask=0;mask<(1<<logv);mask+=2)for(int i=1;i<logv;i++)if((mask&(1<<i))!=0){f1[mask]=max(f1[mask],find_l(i,f1[mask^(1<<i)]));f2[mask]=min(f2[mask],find_r(i,f2[mask^(1<<i)])); }for(int i=1;i<=cnt[0];i++){int lft=l[0][i];int rit=r[0][i];for(int mask=0;mask<(1<<logv);mask+=2){int mask2=((1<<logv)-2)^mask;if(f1[mask]>=lft-1&&f2[mask2]<=rit+1){ans[i]=1;break;}}}int las=1;for(int i=1;i<=n;i++){if(i>r[0][las])las++;if(ans[las]==0)PF("Impossible\n");elsePF("Possible\n");} }總結
以上是生活随笔為你收集整理的【DP】AGC012 ECamel and Oases的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML中的img标签无法显示图片的解决
- 下一篇: dm9000 晶振测不准