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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CF718E Matvey‘s Birthday(状压、bfs、暴力、分类讨论)

發(fā)布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF718E Matvey‘s Birthday(状压、bfs、暴力、分类讨论) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

解析

比較復(fù)雜的一道題
看數(shù)據(jù)范圍,我們肯定要從種類很少的顏色入手

因為第二種加邊方式和顏色密切相關(guān)
所以設(shè)計disi,kdis_{i,k}disi,k?表示 i 號節(jié)點到顏色為 k 的節(jié)點的最小步數(shù)
通過對每個k bfs一遍就能得出答案
然后兩個點之間的距離就可以寫出轉(zhuǎn)移式:
fi,j=min?(∣i?j∣,min?k8disi,k+disj,k+1)f_{i,j}=\min (|i-j|, \min_k^8dis_{i,k}+dis_{j,k}+1)fi,j?=min(i?j,kmin8?disi,k?+disj,k?+1)
考慮這樣我們就得到了一種n2n^2n2的算法

考慮如何加速
首先,由于最差情況就是aabbcc…這樣的情形,答案不會超過15,所以第一項我們只需要在距離[i-15,i-1]的區(qū)間考慮,可以暴力求解

關(guān)鍵是對后面一項的處理

設(shè)計coli,jcol_{i,j}coli,j?表示從任意 i 顏色的塊走到任意 j 顏色的塊的最小步數(shù)
這個也可以在bfs時順便轉(zhuǎn)移
可以得到一個不等關(guān)系式:
colai,j≤disi,j≤colai,j+1col_{a_i,j}\leq dis_{i,j}\leq col_{a_i,j}+1colai?,j?disi,j?colai?,j?+1
為什么?
也比較顯然,如果任何一個不等關(guān)系不符合,col和dis數(shù)組就會在bfs時互相更新,使這個不等關(guān)系重新滿足

所以,我們的dis-col的差值只可能為0或1,我們可以把8個對應(yīng)的差值狀態(tài)壓縮,然后一起求解

實現(xiàn)上,建議把所有狀態(tài)的結(jié)果預(yù)處理出來,會在瓶頸部分少一個8的循環(huán),應(yīng)該快很多

代碼

#include<bits/stdc++.h>const int N=1e5+100; const int mod=1e9+7; #define ll long long using namespace std; inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; }int n,m;int col[9][9],dis[N][9],a[N]; bool vis[N]; char s[N]; int q[N],st,ed; int dx[3]={0,1,-1}; vector<int>v[9]; void bfs(int k){memset(vis,0,sizeof(vis));st=1;ed=0;for(int i=1;i<=n;i++){if(a[i]==k) q[++ed]=i,vis[i]=1;}col[k][k]=0;while(st<=ed){int now=q[st++];for(int i=1;i<=2;i++){int to=now+dx[i];if(vis[to]||to==0||to>n) continue;vis[to]=1;dis[to][k]=dis[now][k]+1;q[++ed]=to;}if(col[k][a[now]]==1e9){col[k][a[now]]=dis[now][k];for(int i=0,tp=v[a[now]].size();i<tp;i++){int x=v[a[now]][i];if(!vis[x]){dis[x][k]=dis[now][k]+1;q[++ed]=x;vis[x]=1;}}}}return; } int mi[15],cst[2060][2060]; int sta[N],num[2060]; int main(){ #ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout); #endifn=read();scanf(" %s",s+1);for(int i=1;i<=8;i++){for(int j=1;j<=8;j++) col[i][j]=1e9;}for(int i=1;i<=n;i++) a[i]=s[i]-'a'+1,v[a[i]].push_back(i);for(int i=1;i<=8;i++) bfs(i);mi[0]=1;for(int i=1;i<=11;i++) mi[i]=mi[i-1]<<1;for(int i=0;i<mi[11];i++){for(int j=0;j<mi[11];j++){int a=(i>>8)+1,b=(j>>8)+1;int res=2e9;for(int k=1;k<=8;k++){res=min(res,col[a][k]+1+col[b][k]+((i&mi[k-1])?1:0)+((j&mi[k-1])?1:0));}cst[i][j]=res;}}for(int i=1;i<=n;i++){int s=a[i]-1,o=a[i];for(int k=8;k>=1;k--){s<<=1;if(dis[i][k]>col[o][k]) s|=1;}sta[i]=s;}int ans(0);ll sum(0);for(int i=1;i<=n;i++){for(int j=max(i-15,1);j<i;j++){int w=min(i-j,cst[sta[i]][sta[j]]);if(w>ans){ans=w;sum=1;}else if(w==ans) sum++;}for(int s=0;s<mi[11];s++){if(!num[s]) continue;if(cst[s][sta[i]]>ans) ans=cst[s][sta[i]],sum=num[s];else if(cst[s][sta[i]]==ans) sum+=num[s];}if(i>=16) num[sta[i-15]]++;}//printf("st[1]=%d st[7]=%d\n",sta[1],sta[7]);//printf("dis[1][1]=%d col[3][1]=%d\n",dis[1][1],col[3][1]);printf("%d %lld\n",ans,sum);return 0; }

總結(jié)

以上是生活随笔為你收集整理的CF718E Matvey‘s Birthday(状压、bfs、暴力、分类讨论)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。