Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 + Div. 2)
阿新 • • 發佈:2021-07-25
A
容易發現只有進位的時候會出現這種情況。
所以直接輸出\(\frac{n+1}{10}\)即可。
code:
int T,n;
int main(){
freopen("1.in","r",stdin);
scanf("%d",&T);while(T--){
scanf("%d",&n);printf("%d\n",(n+1)/10);[]
}
}
B
暴力列舉兩個端點,然後折回去看能不能成立時間複雜度\(O(n^3)\)
但是其實可以hash做到\(O(n^2)\),大概是因為B題沒有加強。
code:
using namespace std; int n,m,k,T;char s1[N+5],s2[N+5]; I int check(int l,int r){ re int i;if(r*2-l<m||r-l+1>m) return 0;for(i=l;i<=r;i++) if(s1[i]^s2[i-l+1]) return 0; for(i=r-1;i>=r-(m-(r-l+1));i--) if(s1[i]^s2[r-i+r-l+1])return 0;return 1; } I void solve(){ re int i,j,h;scanf("%s",s1+1);scanf("%s",s2+1);n=strlen(s1+1);m=strlen(s2+1); for(i=1;i<=n;i++){ for(j=i;j<=n;j++)if(check(i,j)){printf("YES\n");return;} }printf("NO\n"); } int main(){ freopen("1.in","r",stdin); re int i;scanf("%d",&T);while(T--)solve(); }
C
直接對每個問號爆搜然後取個min即可。
code:
using namespace std; int T,fl[N+5],now1,now2,ans,n=10;char s[N+5]; I void calc(){ re int i;now1=now2=0;for(i=1;i<=n;i++){ if(i&1)now1+=(s[i]=='1');else now2+=(s[i]=='1'); if((now1>now2&&(n-i+1)/2<now1-now2)||(now1<now2&&(n-i)/2<now2-now1)) {ans=min(ans,i);return;} } } I void dfs(int x){ if(x==n+1) return calc();if(fl[x]) s[x]='0',dfs(x+1),s[x]='1',dfs(x+1);else dfs(x+1); } I void solve(){ re int i;scanf("%s",s+1);for(i=1;i<=n;i++) fl[i]=(s[i]=='?');ans=10;dfs(1);printf("%d\n",ans); } int main(){ freopen("1.in","r",stdin); scanf("%d",&T);while(T--) solve(); }
D
對起點是奇數起點還是偶數起點兩個都算一下即可。
注意要判是否在終點之後也是偶數,我就FST在這裡。
code:
int T,n,m,r,las,flag;char s1[N+5],s2[N+5]; I void solve(){ re int i;scanf("%s%s",s1+1,s2+1);n=strlen(s1+1);m=strlen(s2+1);r=1;las=0;flag=0; for(i=1;i<=m;i++){ while(r<=n&&(s1[r]^s2[i]||((r-las)%2==0))) r++; if(r==n+1)break;las=r;r+=(i!=m); }flag|=(r!=n+1&&(n-r+1)&1); r=las=1;for(i=1;i<=m;i++){ while(r<=n&&(s1[r]^s2[i]||((r-las)%2==0))) r++; if(r==n+1)break;las=r;r+=(i!=m); }flag|=(r!=n+1&&(n-r+1)&1); puts(flag?"Yes":"No"); } int main(){ freopen("1.in","r",stdin); scanf("%d",&T);while(T--) solve(); }
E
沒看到\(m\leq \frac{n}{3}\)太日了。
可以發現我們最多換\(\frac{2n}{3}\)個位置所以有至少\(\frac{n}{3}\)個位置不動。
然後我們又知道一個點只在一個迴圈中不動。
所以答案不超過\(3\)
然後暴力數連通塊個數即可。
code:
int n,m,T,A[N+5],pl[N+5],F[N+5],cnt,Ans[N+5],fa[N+5],ToT,un,wn;
I int Getfa(int x){return x==fa[x]?x:fa[x]=Getfa(fa[x]);}
I void merge(int x,int y){
un=Getfa(x);wn=Getfa(y);un^wn&&(fa[un]=wn,ToT--);
}
I void Solve(){
re int i,j;for(i=0;i<=2*n;i++) F[i]=0;cnt=0;scanf("%d%d",&n,&m);for(i=1;i<=n;i++) scanf("%d",&A[i]),pl[A[i]]=i;
for(i=1;i<=n;i++) pl[i+n]=pl[i];for(i=1;i<=n*2;i++) i>=pl[i]&&(F[i-pl[i]]++);
for(i=0;i<n;i++){
if(F[i]<n-2*m) continue;for(j=1;j<=n;j++) fa[j]=j;ToT=n;for(j=i+1;j<=i+n;j++) merge(j-i,pl[j]);
n-ToT<=m&&(Ans[++cnt]=(n-i)%n);
}sort(Ans+1,Ans+cnt+1);printf("%d ",cnt);for(i=1;i<=cnt;i++) printf("%d ",Ans[i]);puts("");
}
int main(){
freopen("1.in","r",stdin);
re int i;scanf("%d",&T);while(T--) Solve();
}
F
為什麼我的分塊和樹狀陣列一樣快啊。
首先我們考慮這個式子,其實要求\(G_{i-1}+\sum\limits_{j=1}^{i}{A_i\%A_j}+\sum\limits_{j=1}^{i}{A_j\%A_i}\)後面那個實在平凡暴力跳就好了反正調和級數\(O(nlogn)\),我們看前面那個。
拆成\(\sum\limits_{j=1}^{i}{A_i-A_j\times \lfloor \frac{A_i}{A_j}\rfloor}\)
後面那個直接整除分塊+樹狀陣列維護即可,時間複雜度\(O(n\sqrt wlog w)\)
然後觀察到我們有\(n\)次修改但是有\(n\sqrt w\)次查詢,所以按\(\sqrt w\)分塊就可以\(O(n\sqrt w)\)了。
但是他們兩個跑得一樣快……
code:
int n,k,x,y,z,Maxn;ll G[N+5],ToT,A[N+5],F[N+5];
struct Tree{
ll F[N+5],Q[N+5];
I void get(int x,int y){re int i;for(i=x;i<x/k*k+k;i++)F[i]+=y;for(i=x/k+1;i<=Maxn/k;i++)Q[i]+=y;}
I ll find(int x,int y){return (F[y]+Q[y/k])-(F[x-1]+Q[(x-1)/k]);}
}S1,S2;
I ll calc1(int m){
re int i,j;ll Ans=0;for(i=1;i<=m;i=j+1)j=m/(m/i),Ans+=1ll*(m/i)*S1.find(i,j);return Ans;
}
I ll calc2(int m){
re int i,j;ll Ans=0;for(i=0;i<=Maxn;i+=m){
Ans+=1ll*(i/m)*m*S2.find(i,min(i+m-1,Maxn));
}return Ans;
}
int main(){
freopen("1.in","r",stdin);freopen("1.out","w",stdout);
re int i;scanf("%d",&n);k=sqrt(n);for(i=1;i<=n;i++) scanf("%lld",&A[i]),Maxn=max(Maxn,A[i]);
for(i=1;i<=n;i++){
G[i]=A[i]*(i-1)+ToT;G[i]-=calc1(A[i])+calc2(A[i]);//printf("%lld %lld\n",calc1(A[i]),calc2(A[i]));
G[i]+=G[i-1];S1.get(A[i],A[i]);S2.get(A[i],1);ToT+=A[i];printf("%lld ",G[i]);
}
}