intfind(int x){ while (f[x] != x) { x = f[x] = f[f[x]]; } return x; }
boolmerge(int x, int y){ x = find(x); y = find(y); if (x == y) { returnfalse; } siz[x] += siz[y]; f[y] = x; returntrue; }
intsize(int x){ return siz[find(x)]; }
boolsame(int x, int y){ returnfind(x) == find(y); } }; voidsolve() { int n; cin>>n; DSU dsu(n); for (int i = 0; i < n; ++i) { int x; cin>>x; dsu.merge(i,x-1); } string s; cin>>s; std::vector<int> ans(n,0); for (int i = 0; i < n; ++i) { if(s[i]=='0') { int fa=dsu.find(i); ans[fa]++; } } for (int i = 0; i < n; ++i) { int fa=dsu.find(i); cout<<ans[fa]<<" \n"[i==n-1]; } } intmain() { int t=1; cin>>t; for(int i=1;i<=t;i++) { //cout<<"case "<<t<<": "; solve(); } return0; }
E
原来打了一个暴力,但是TLE了。
思路
偶数的情况比较好处理。奇数的情况比较麻烦,直接暴力会TLE。
可以遍历不选第i个字符的情况,这里可以使用前缀和进行优化。
我们可以先计算前i个字符中,26个字符出现的情况。
然后在不选第i个字符时,直接计算偏移一位的前缀和即可。
代码
#include<bits/stdc++.h> usingnamespace std; using ll=longlong; voidsolve() { int n; cin>>n; string s; cin>>s; if(n==1) { cout<<1<<"\n"; return; } elseif(n==2) { cout<<0<<"\n"; return; } int ans=1e9; if(n&1) { s='#'+s; std::vector<std::vector<int>> odd(n+1,std::vector<int>(26)); std::vector<std::vector<int>> even(n+1,std::vector<int>(26)); for (int i = 1; i <= n; ++i) { odd[i]=odd[i-1]; even[i]=even[i-1]; if(i%2==0) even[i][s[i]-'a']++; else odd[i][s[i]-'a']++; } int omax=0,emax=0; int ocnt=0,ecnt=0; for (int i = 1; i <= n; ++i) { omax=0,emax=0; for (int j = 0; j < 26; ++j) { ocnt=odd[i-1][j]+even[n][j]-even[i][j]; ecnt=even[i-1][j]+odd[n][j]-odd[i][j]; omax=max(ocnt,omax); emax=max(ecnt,emax); } ans=min(ans,n-omax-emax); } cout<<ans<<"\n"; } else { std::map<int, int> even; std::map<int, int> odd; for (int i = 0; i < n; ++i) { if(i&1) { even[s[i]]++; } else { odd[s[i]]++; } } int omax=0,emax=0; for (auto [x,y]: even) { emax=max(emax,y); } for (auto [x,y]: odd) { omax=max(omax,y); } ans=n-omax-emax; cout<<ans<<"\n"; } } intmain() { int t=1; cin>>t; for(int i=1;i<=t;i++) { //cout<<"case "<<t<<": "; solve(); } return0; }
F
WA了十发。。。
思路
就是直接求期望,直接找个模板计算逆元即可。使用前缀和优化一下。
该死的取模运算。
代码
#include<bits/stdc++.h> usingnamespace std; using ll=longlong; const ll mod=1e9+7; ll qpow(ll a, ll n, ll p)// 快速幂 { ll ans = 1; while (n) { if (n & 1) ans = ans % p * a % p; a = a % p * a % p; n >>= 1; } ans%=mod; return ans; } ll inv(ll a, ll p) { returnqpow(a, p - 2, p); } voidsolve() { int n; cin>>n; std::vector<ll> a(n,0); std::vector<ll> sum(n,0); for (int i = 0; i < n; ++i) { cin>>a[i]; } sum[0]=a[0]; for (int i = 1; i < n; ++i) { sum[i]=sum[i-1]+a[i]; } ll ans=0; for (int i = 0; i < n; ++i) { ans=(ans%mod+((a[i]%mod)*((sum[n-1]-sum[i])%mod)%mod)%mod)%mod; } ll cnt=(((((n-1)%mod)*(n%mod))%mod)%mod)*(inv(2,mod)%mod)%mod; cout<<((ans%mod)*(inv(cnt,mod)%mod))%mod<<"\n"; } intmain() { int t=1; cin>>t; for(int i=1;i<=t;i++) { //cout<<"case "<<t<<": "; solve(); } return0; }
#include<bits/stdc++.h> usingnamespace std; using ll=longlong; const string narek="narek"; voidsolve() { int n,q; cin>>n>>q; std::vector<int> pref(n+2,0); for (int i = 0; i < n; ++i) { int x; cin>>x; pref[x+1]++; } for (int i = 0; i <= n; ++i) { pref[i+1]+=pref[i]; } std::vector<int> ans(n+1,0); auto check=[&](int x,int mid) { int cnt=0; for (int i = 0; i <= n+1; i+=x) { cnt+=pref[min(i+mid,n+1)]-pref[i]; } if(cnt<=n/2) { returntrue; } elsereturnfalse; }; for (int i = 1; i <= n; ++i) { int l=0,r=i-1; //二分中位数的值 while(l<r) { int mid=(l+r+1)>>1; if(check(i,mid)) { l=mid; } else { r=mid-1; } } ans[i]=l; } for (int i = 0; i < q; ++i) { int x; cin>>x; cout<<ans[x]<<" \n"[i==q-1]; } } intmain() { int t; cin>>t; for (int i = 1; i <= t ; ++i) { //cout<<"case "<<i<<": "<<"\n"; solve(); } return0; }
Code 2
官方题解
#include<bits/stdc++.h>
usingnamespace std;
intmain() { int t=1; cin>>t; for(int i=1;i<=t;i++) { int n,m; cin>>n>>m; vector<int>a(n); vector<int>c(n+1,0ll); for(int i=0;i<n;i++) { cin>>a[i]; c[a[i]]++; } for(int i=1;i<=n;i++) { c[i]+=c[i-1]; } int res[n+1]={0}; for(int x=1;x<=n;x++) { int l=0,r=x; while(l<r) { int mid=(l+r)/2; int cnt=c[mid]; for(int k=1;k*x<=n;k++) { cnt+=c[min(k*x+mid,n)]-c[k*x-1]; } if(cnt-1>=n/2) { r=mid; } else { l=mid+1; } } res[x]=l; } while(m--) { int x; cin>>x; cout<<res[x]<<" "; } cout<<endl; } }