2025多校冲刺省选模拟赛13
2025多校冲刺省选模拟赛13
A. 逆序对
-
部分分
:爆搜。
点击查看代码
int a[50]; pair<int,ll>ans[50]; struct BIT { int c[50]; int lowbit(int x) { return x&(-x); } void add(int x,int val) { for(int i=x;i>=1;i-=lowbit(i)) c[i]+=val; } int getsum(int n,int x) { int ans=0; for(int i=x;i<=n;i+=lowbit(i)) ans+=c[i]; return ans; } }B; void dfs(int pos,int n,int len,int sum) { if(pos==n+1) { if(ans[len].first>sum) ans[len]=make_pair(sum,1ll); else if(ans[len].first==sum) ans[len].second++; } else { B.add(a[pos],1); dfs(pos+1,n,len+1,sum+B.getsum(n,a[pos]+1)); B.add(a[pos],-1); dfs(pos+1,n,len,sum); } } int main() { #define Isaac #ifdef Isaac freopen("des.in","r",stdin); freopen("des.out","w",stdout); #endif int n,i; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; memset(ans,0x3f,sizeof(ans)); dfs(1,n,0,0); for(i=1;i<=n;i++) cout<<ans[i].first<<" "<<ans[i].second<<endl; return 0; }
-
正解
- 折半搜索瓶颈在于无法快速合并两个区间的答案,没有前途。
- 考虑状压,设
表示 中选出的数的集合为 时的逆序对数, 的状态数无法接受,需要进一步优化。 - 观察到对于后续加入
的贡献,我们只关心 内元素的数量(钦定 为 升序排序后的结果)。不妨将每一段内元素的数量作为状态进行转移。由 相关理论 可知和为 的若干个数的积最大为 ,若必须为正整数则最大值规模大概是 。 - 集合
直接作为下标的话需要哈希表进行辅助,不妨直接将每段的长度作为当前段数的进制转成int
类型的数作为下标,询问时再进行反着解码回去即可。 - 转移时枚举下一位选或不选刷表转移即可,注意因两段合成一段的下标移位问题。
点击查看代码
int a[50],suf[50][50],d[50],c[50][50]; vector<pair<int,ll> >f[50]; pair<int,ll> sx_min(pair<int,ll> a,pair<int,ll> b) { if(a.first==b.first) return make_pair(a.first,a.second+b.second); else return (a.first<b.first)?a:b; } int main() { #define Isaac #ifdef Isaac freopen("des.in","r",stdin); freopen("des.out","w",stdout); #endif int n,id,tmp,sum,i,j,k,w; cin>>n; a[n+1]=n+1; for(i=1;i<=n;i++) cin>>a[i]; for(i=0;i<=n;i++) { for(j=i+1;j<=n+1;j++) { suf[i][0]++; suf[i][suf[i][0]]=a[j]; } sort(suf[i]+1,suf[i]+1+suf[i][0]); for(j=w=1;j<=suf[i][0];j++) { c[i][j]=w; w*=((j==1)?suf[i][j]:(suf[i][j]-suf[i][j-1])); } f[i].resize(w); fill(f[i].begin(),f[i].end(),make_pair(0x3f3f3f3f,0)); } f[0][0]=make_pair(0,1); for(i=0;i<=n-1;i++) { id=0; for(j=1;j<=suf[i][0];j++) if(suf[i][j]==a[i+1]) id=j; for(j=0;j<f[i].size();j++) { w=j; sum=tmp=0; for(k=suf[i][0];k>=1;k--) { d[k]=w/c[i][k]; w%=c[i][k]; if(k>=id+1) sum+=d[k]; if(k==id||k==id+1) tmp+=d[k]*c[i+1][id];// 两段合成一段 else tmp+=d[k]*c[i+1][k-(k>=id+2)];//移位 } f[i+1][tmp]=sx_min(f[i+1][tmp],f[i][j]); tmp+=c[i+1][id];// 段内元素数量 +1 f[i+1][tmp]=sx_min(f[i+1][tmp],make_pair(f[i][j].first+sum,f[i][j].second)); } } for(i=1;i<=n;i++) cout<<f[n][i].first<<" "<<f[n][i].second<<endl; return 0; }
B. 网格图
-
时做法同 2025多校冲刺省选模拟赛9 T2 B.雪雀 。 -
时手推下,对答案的贡献系数为 。 -
时类似 进行分治,但 转移简单了不少。点击查看代码
const ll p=1000000007; ll a[4][200010],L[4][4][200010],R[4][4][200010],d[600010],n,m,ans=0; struct node { ll x,y,val,op; bool operator < (const node &another) const { return (x==another.x)?(op<another.op):(x<another.x); } }; vector<node>q; struct BIT { ll c[2][600010]; void clear() { for(ll i=1;i<=d[0];i++) c[0][i]=c[1][i]=0; } ll lowbit(ll x) { return (x&(-x)); } void add(ll m,ll x,ll val1,ll val2) { for(ll i=x;i<=m;i+=lowbit(i)) { c[0][i]=(c[0][i]+val1)%p; c[1][i]=(c[1][i]+val2)%p; } } ll getsum(ll x,ll val) { ll sum1=0,sum2=0; for(ll i=x;i>=1;i-=lowbit(i)) { sum1=(sum1+c[0][i])%p; sum2=(sum2+c[1][i])%p; } return (sum1+sum2*val%p)%p; } }T; void work() { T.clear(); sort(q.begin(),q.end()); d[0]=0; for(ll i=0;i<q.size();i++) d[++d[0]]=q[i].y; sort(d+1,d+1+d[0]); d[0]=unique(d+1,d+1+d[0])-(d+1); for(ll i=0;i<q.size();i++) { q[i].y=lower_bound(d+1,d+1+d[0],q[i].y)-d; if(q[i].op==0) T.add(d[0],q[i].y,q[i].val%p,1); else ans=(ans+T.getsum(q[i].y,q[i].val%p))%p; } } struct Subtest1 { ll solve() { ll ans=0; for(ll i=1;i<=m;i++) ans=(ans+a[1][i]*2%p*((m-1)%p+(m-i)%p*(i-1)%p)%p)%p; return ans; } }S1; struct Subtest2 { void dp(ll l,ll r,ll mid) { L[1][1][mid]=a[1][mid]; L[1][2][mid]=a[1][mid]+a[2][mid]; L[2][1][mid]=a[1][mid]+a[2][mid]; L[2][2][mid]=a[2][mid]; for(ll op=1;op<=2;op++) { for(ll i=mid-1;i>=l;i--) { L[op][1][i]=min({L[op][1][i+1]+a[1][i],L[op][2][i+1]+a[2][i]+a[1][i]}); L[op][2][i]=min({L[op][2][i+1]+a[2][i],L[op][1][i+1]+a[2][i]+a[1][i]}); } } mid++; R[1][1][mid]=a[1][mid]; R[1][2][mid]=a[1][mid]+a[2][mid]; R[2][1][mid]=a[1][mid]+a[2][mid]; R[2][2][mid]=a[2][mid]; for(ll op=1;op<=2;op++) { for(ll i=mid+1;i<=r;i++) { R[op][1][i]=min({R[op][1][i-1]+a[1][i],R[op][2][i-1]+a[2][i]+a[1][i]}); R[op][2][i]=min({R[op][2][i-1]+a[2][i],R[op][1][i-1]+a[2][i]+a[1][i]}); } } } void solve(ll l,ll r) { if(l==r) { ans=(ans+a[1][l]+a[2][l])%p; return; } ll mid=(l+r)/2; solve(l,mid); solve(mid+1,r); dp(l,r,mid); for(ll z=1;z<=2;z++) { q.clear(); ll x=((z==1)?2:1); for(ll op=1;op<=2;op++) { for(ll i=l;i<=mid;i++) q.push_back((node){L[z][op][i]-L[x][op][i]+(z!=1),0,L[z][op][i],0}); for(ll i=mid+1;i<=r;i++) q.push_back((node){R[x][op][i]-R[z][op][i],0,R[z][op][i],1}); } work(); } } }S2; struct Subtest3 { ll f[200010],g[200010]; void init() { f[0]=g[m+1]=0x3f3f3f3f3f3f3f3f; for(ll i=1;i<=m;i++) f[i]=min(f[i-1],a[2][i])+a[1][i]+a[3][i]; for(ll i=m;i>=1;i--) g[i]=min(g[i+1],a[2][i])+a[1][i]+a[3][i]; } void dp(ll l,ll r,ll mid) { L[1][1][mid]=a[1][mid]; L[1][2][mid]=a[1][mid]+a[2][mid]; L[1][3][mid]=min(f[mid],g[mid]); L[2][1][mid]=a[1][mid]+a[2][mid]; L[2][2][mid]=a[2][mid]; L[2][3][mid]=a[2][mid]+a[3][mid]; L[3][1][mid]=min(f[mid],g[mid]); L[3][2][mid]=a[2][mid]+a[3][mid]; L[3][3][mid]=a[3][mid]; for(ll op=1;op<=3;op++) { for(ll i=mid-1;i>=l;i--) { L[op][1][i]=min({L[op][1][i+1]+a[1][i],L[op][2][i+1]+a[2][i]+a[1][i],L[op][3][i+1]+f[i]}); L[op][3][i]=min({L[op][1][i+1]+f[i],L[op][2][i+1]+a[2][i]+a[3][i],L[op][3][i+1]+a[3][i]}); L[op][2][i]=min({L[op][1][i]+a[2][i],L[op][2][i+1]+a[2][i],L[op][3][i]+a[2][i]}); } } mid++; R[1][1][mid]=a[1][mid]; R[1][2][mid]=a[1][mid]+a[2][mid]; R[1][3][mid]=min(f[mid],g[mid]); R[2][1][mid]=a[1][mid]+a[2][mid]; R[2][2][mid]=a[2][mid]; R[2][3][mid]=a[2][mid]+a[3][mid]; R[3][1][mid]=min(f[mid],g[mid]); R[3][2][mid]=a[2][mid]+a[3][mid]; R[3][3][mid]=a[3][mid]; for(ll op=1;op<=3;op++) { for(ll i=mid+1;i<=r;i++) { R[op][1][i]=min({R[op][1][i-1]+a[1][i],R[op][2][i-1]+a[2][i]+a[1][i],R[op][3][i-1]+g[i]}); R[op][3][i]=min({R[op][1][i-1]+g[i],R[op][2][i-1]+a[2][i]+a[3][i],R[op][3][i-1]+a[3][i]}); R[op][2][i]=min({R[op][1][i]+a[2][i],R[op][2][i-1]+a[2][i],R[op][3][i]+a[2][i]}); } } } void solve(ll l,ll r) { if(l==r) { ans=(ans+a[1][l]+2*a[2][l]+a[3][l]+min(f[l],g[l]))%p; return; } ll mid=(l+r)/2; solve(l,mid); solve(mid+1,r); dp(l,r,mid); for(ll z=1;z<=3;z++) { q.clear(); ll x=((z==1)?2:1),y=((z==3)?2:3); for(ll op=1;op<=3;op++) { for(ll i=l;i<=mid;i++) q.push_back((node){L[z][op][i]-L[x][op][i]+(z!=1),L[z][op][i]-L[y][op][i]+(z==3),L[z][op][i],0}); for(ll i=mid+1;i<=r;i++) q.push_back((node){R[x][op][i]-R[z][op][i],R[y][op][i]-R[z][op][i],R[z][op][i],1}); } work(); } } }S3; int main() { #define Isaac #ifdef Isaac freopen("grid.in","r",stdin); freopen("grid.out","w",stdout); #endif cin>>n>>m; for(ll i=1;i<=n;i++) { for(ll j=1;j<=m;j++) cin>>a[i][j]; } if(n==1) cout<<S1.solve(); if(n==2) { S2.solve(1,m); cout<<ans*2%p<<endl; } if(n==3) { S3.init(); S3.solve(1,m); cout<<ans*2%p<<endl; } return 0; }
HZTG2487. 选拔
-
部分分
:输出大样例。 :预处理所有字符串的哈希值。
点击查看代码
#include<bits/extc++.h> using namespace __gnu_pbds; const ll mod=1000003579,base=13331; struct node { int nxt,to,w; }e[60010]; int head[30010],hsh[30010],cnt=0; gp_hash_table<int,bool>vis; char s[30010]; void add(int u,int v,int w) { cnt++; e[cnt]=(node){head[u],v,w}; head[u]=cnt; } int sx_hash(char s[],int len) { int ans=0; for(int i=1;i<=len;i++) ans=(1ll*ans*base%mod+s[i])%mod; return ans; } void dfs(int x,int fa) { vis[hsh[x]]=1; for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa) { hsh[e[i].to]=(1ll*hsh[x]*base%mod+e[i].w)%mod; dfs(e[i].to,x); } } } int main() { #define Isaac #ifdef Isaac freopen("selection.in","r",stdin); freopen("selection.out","w",stdout); #endif int n,m,u,v,i; char c; cin>>n; if(n==30000) { cout<<"NO\nYES\nNO\nNO\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nNO\nNO\nNO\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nNO\nNO\nNO\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nNO\nNO\nNO\nNO\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nYES\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nYES\nNO\nYES\nNO\nNO\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nYES\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nYES\nNO\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nNO\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nNO\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nYES\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nYES\nYES\nYES\nNO\nNO\nNO\nNO\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nNO\nNO\nNO\nYES\nYES\nYES\nYES\nYES\nYES\nYES\nNO\nYES\nNO\nNO\nNO\nYES\n"; } else { for(i=1;i<=n-1;i++) { cin>>u>>v>>c; add(u,v,c); add(v,u,c); } for(i=1;i<=n;i++) { hsh[i]=0; dfs(i,0); } cin>>m; for(i=1;i<=m;i++) { cin>>(s+1); cout<<((vis.find(sx_hash(s,strlen(s+1)))==vis.end())?"NO":"YES")<<endl; } } return 0; }
:每组询问按位遍历所有字符串。
点击查看代码
struct node { int nxt,to; char w; }e[60010]; int head[30010],cnt=0,len,f[30010],g[30010],limit; char s[30010]; void add(int u,int v,char w) { cnt++; e[cnt]=(node){head[u],v,w}; head[u]=cnt; } bool dfs(int x,int fa,int tot) { if(tot==len+1) return true; for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa&&e[i].w==s[tot]&&dfs(e[i].to,x,tot+1)==true) { return true; } } return false; } void dfs(int x,int fa) { f[x]=g[x]=0; for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=fa) { dfs(e[i].to,x); if(f[e[i].to]+1>f[x]) { g[x]=f[x]; f[x]=f[e[i].to]+1; } else g[x]=max(g[x],f[e[i].to]+1); } } limit=max(limit,f[x]+g[x]); } int main() { #define Isaac #ifdef Isaac freopen("selection.in","r",stdin); freopen("selection.out","w",stdout); #endif int n,m,u,v,flag,i,j; char c; cin>>n; for(i=1;i<=n-1;i++) { cin>>u>>v>>c; add(u,v,c); add(v,u,c); } dfs(1,0); cin>>m; for(i=1;i<=m;i++) { cin>>(s+1); len=strlen(s+1); flag=0; for(j=1;j<=n&&flag==0&&len<=limit;j++) { if(dfs(j,0,1)==true) flag=1; } cout<<((flag==0)?"NO":"YES")<<endl; } return 0; }
-
正解
- 观察到模式串的出现方式一定是一条从下到上的路径和一条从上到下的路径拼起来。
- 设
表示从下到上走到 能否匹配 , 表示从上到下从 出发能否匹配 。将所有模式串用特殊字符隔开后用bitset
加速即可。 - 一种方便的代码实现是每两个模式串之间用两个特殊字符隔开分别作为前一个串的末尾和后一个串的开头辅助转移(即某条路径为空的情况),但空间开不下。单独处理路径为空的情况即可。
- 在
的途中转移会爆递归栈。
点击查看代码
struct node { int nxt,to,w; }e[60010]; int head[30010],l[30010],r[30010],fa[30010],pos[30010],w[30010],tot=0,cnt=0; bitset<60010>f[30010],g[30010],id[30],ans[3]; char s[60010],t[30010]; void add(int u,int v,int w) { cnt++; e[cnt]=(node){head[u],v,w}; head[u]=cnt; } void dfs(int x,int father) { fa[x]=father; tot++; pos[tot]=x; for(int i=head[x];i!=0;i=e[i].nxt) { if(e[i].to!=father) { w[e[i].to]=e[i].w; dfs(e[i].to,x); } } } int main() { #define Isaac #ifdef Isaac freopen("selection.in","r",stdin); freopen("selection.out","w",stdout); #endif int n,m,len=0,_len,u,v,flag,i,j; char c; cin>>n; for(i=1;i<=n-1;i++) { cin>>u>>v>>c; add(u,v,c-'a'+1); add(v,u,c-'a'+1); } dfs(1,0); cin>>m; for(i=1;i<=m;i++) { cin>>(t+1); _len=strlen(t+1); len++; s[len]='#'; l[i]=len+1; for(j=1;j<=_len;j++) { len++; s[len]=t[j]; } r[i]=len; } for(i=1;i<=len;i++) id[(s[i]=='#')?27:s[i]-'a'+1][i]=1; for(i=1;i<=n;i++) f[i]=g[i]=id[27]; for(i=n;i>=1;i--) { u=pos[i]; v=fa[u]; ans[1]|=f[u]; ans[2]|=g[u]; ans[0]|=(f[u]<<1)&id[w[u]]&(g[v]>>1); ans[0]|=(f[v]<<1)&id[w[u]]&(g[u]>>1); f[v]|=(f[u]<<1)&id[w[u]]; g[v]|=(g[u]>>1)&id[w[u]]; } for(i=1;i<=m;i++) { flag=ans[1][r[i]]|ans[2][l[i]]; for(j=l[i];j<=r[i];j++) flag|=ans[0][j]; cout<<(flag==0?"NO":"YES")<<endl; } return 0; }
C. 种苹果
-
原题: LibreOJ 6039. 「雅礼集训 2017 Day5」珠宝 /「NAIPC2016」Jewel Thief
-
部分分
:暴力进行背包。
点击查看代码
const ll p=998244353; ll f[1500010],b[300010],c[300010]; int main() { #define Isaac #ifdef Isaac freopen("apple.in","r",stdin); freopen("apple.out","w",stdout); #endif ll n,m=0,ans=0,base=20201205,i,j; scanf("%lld",&n); for(i=1;i<=n;i++) { scanf("%lld",&b[i]); m+=b[i]; } for(i=1;i<=n;i++) { scanf("%lld",&c[i]); for(j=m;j>=b[i];j--) f[j]=max(f[j],f[j-b[i]]+c[i]); } for(i=1;i<=m+1;i++) f[i-1]%=p; for(i=1;i<=m+1;i++,base=base*20201205%p) ans=(ans+base*f[i-1]%p)%p; printf("%lld\n",ans); return 0; }
-
正解
- 对同一重量的价值降序排序,内部选择时一定是一段前缀。
- 设
表示仅考虑重量 时重量 时的最大价值,状态转移方程为 ,其中 为重量为 的前缀和。 - 观察到
,考虑按照余数进行分组,则有 ,其中 。 - 进一步地,观察到转移过程中具有决策单调性。具体地,若
则后续过程 一定不如 优,考虑新加入的长度为 的贡献 。 - 分治法加速即可。
点击查看代码
const ll p=998244353; ll f[1500010],g[1500010],tmp[1500010],sum[1500010],x[1500010],y[1500010]; vector<ll>v[10]; void solve(ll l,ll r,ll x,ll y) { if(l>r) return; ll mid=(l+r)/2,opt=0; g[mid]=-0x3f3f3f3f3f3f3f; for(ll i=x;i<=min(y,mid);i++) { if(tmp[i]+sum[mid-i]>g[mid]) { g[mid]=tmp[i]+sum[mid-i]; opt=i; } } solve(l,mid-1,x,opt); solve(mid+1,r,opt,y); } int main() { #define Isaac #ifdef Isaac freopen("apple.in","r",stdin); freopen("apple.out","w",stdout); #endif ll n,m=0,ans=0,base=20201205,i,j,k; cin>>n; for(i=1;i<=n;i++) { cin>>x[i]; m+=x[i]; } for(i=1;i<=n;i++) { cin>>y[i]; v[x[i]].push_back(y[i]); } for(i=1;i<=5;i++) { if(v[i].empty()==1) continue; sort(v[i].begin(),v[i].end(),greater<ll>()); for(j=1;j<=m/i;j++) sum[j]=sum[j-1]+(j-1<v[i].size()?v[i][j-1]:0);// 因状态设计中表示的是 <=j 的最大价值,所以后面的也要处理(其实是分治的写法问题) for(j=0;j<=i-1;j++) { for(k=0;i*k+j<=m;k++) tmp[k]=f[i*k+j]; k--; solve(0,k,0,k); for(k=0;i*k+j<=m;k++) f[i*k+j]=g[k]; } } for(i=1;i<=m+1;i++) f[i-1]%=p; for(i=1;i<=m+1;i++,base=base*20201205%p) ans=(ans+base*f[i-1]%p)%p; printf("%lld\n",ans); return 0; }
总结
- 想了一整场
怎么折半搜索。 因 之前多校模拟赛出过,遂 换题了。
后记
- 题面中含有较多错别字。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18717155,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
2024-02-15 2024寒假年后集训日记