【學習筆記】2021.10.9 - zhengru IOI 七連測 Day6
阿新 • • 發佈:2021-10-10
T1聚會
正解
思路
-
簡單題,開棧暴力儲存每個 1 的位置,然後暴力向兩邊拓展更新答案即可。
-
當拓展到另一個 1 時應該立即停止,因為再進行拓展一定會多上一個 兩個 1 之間的距離,一定不會更優,沒有意義。
-
至此,每一段區間最多被遍歷兩次,複雜度 \(O(Tn)\) ,可以通過。
程式碼
屑程式碼
#include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> using namespace std; int T,n,ans[500233],stk[500233],tot,Case=0; char ch[500233]; long long ouout; inline int R(){ int x=0,f=1;char c='c'; while(c>'9'||c<'0'){f=f*(c=='-'?-1:1);c=getchar();} while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();} return x*f; } inline void gechch(){ char c='c';int pos=0; while(c!='1'&&c!='0') c=getchar(); while((++pos)&&(c=='1'||c=='0')){ans[pos]=((c=='1')?0*(stk[++tot]=pos):1919810);c=getchar();} return; } int main(){ T=R(); while(T--){ tot=0;ouout=0; n=R(); gechch(); for(register int i=1;i<=tot;++i){ for(register int j=stk[i]-1;ans[j];--j){if(ans[j]<=stk[i]-j) break;ans[j]=stk[i]-j;} for(register int j=stk[i]+1;ans[j];++j) ans[j]=j-stk[i]; } for(register int i=1;i<=n;++i) ouout+=ans[i]; printf("Case #%d: %lld\n",++Case,ouout); } return 0; }