cf673div2C. k-Amazing Numbers
原题:https://codeforces.com/contest/1417/problem/C
题意:给定一个数组a,长度为n,amazingk为大小为i的所有子串中都有的最小的数字。输出i=1~n的k
参考博客:https://blog.csdn.net/ACkingdom/article/details/108848337
思路:
loc[v]记录数据v出现的当前位置
dis[v]通过loc[v]的前后相减得到v和v之间的最大距离(也就是让v成为amazingk的最小size
ans[i]记录size恰好为i时的最小amazingk(注意:如果size比i大的amazingk无法被记录,所以后面在输出答案的时候需要继续处理
最后输出的思路:
从size=1开始遍历
res初始值为-1,正常情况下记录的是到当前size为止的最小amazingk
1如果ans[i]==0 直接输出res(因为如果res是小于size的长度的amazingk,那么也一定是size的amazingk
2如果ans[i]不为0,那么更新res的值。然后输出res。
代码:
1 #include "iostream" 2 #include "cstring" 3 #define ll long long 4 #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 5 const ll mx=3e5+10; 6 using namespace std; 7 ll a[mx],loc[mx],dis[mx],ans[mx], n; 8 int main() 9 { 10 IOS; 11 ll T; 12 cin>>T; 13 for(ll lp=1;lp<=T;lp++){ 14 cin>>n; 15 memset(loc,0,sizeof loc); 16 memset(dis,0,sizeof dis); 17 memset(ans,0,sizeof ans); 18 for(ll i=1;i<=n;i++){ 19 cin>>a[i]; 20 dis[a[i]]=max(dis[a[i]],i-loc[a[i]]);//滚动记录两个数据大小为a[i]的数据之间的最大距离 21 loc[a[i]]=i; 22 } 23 for(ll i=1;i<=n;i++){ 24 dis[a[i]]=max(n-loc[a[i]]+1,dis[a[i]]);//记录最后一个a[i]到末尾的距离 25 } 26 //dis[i]=对于v为i的值实现共有的最小距离size 27 //ans[i]记录对于size为i的最小答案 28 for(ll i=1;i<=n;i++)//对于v:1~n 29 { 30 if(ans[dis[i]]==0){ 31 //如果v=i存在, 那么对于该v需要size=dis[i] 32 //ans[size]=i;对于该size有一个满足共有的数据i 并且是最小的数据 33 //但是size+1可能就没有记录到该i 所以后续输出的时候需要res辅助记录最小amazingk 34 ans[dis[i]]=i; 35 } 36 } 37 ll res=-1; 38 for(ll i=1;i<=n;i++){ 39 if(i!=1) cout<<" "; 40 if(ans[i]==0){//取res 41 cout<<res; 42 } 43 else{ 44 res=(res==-1)?ans[i]:min(res, ans[i]);//如果是-1就赋值,如果不是-1取最小值 45 cout<<res; 46 } 47 } 48 cout<<endl; 49 } 50 return 0; 51 }
我的误区:
我一直想如何求对于长度为i的子串中公有的最小数字。
但是参考博客的思路是对于一个数字求出使它成为amazingk的最小size。
两个想法的对象反过来了。