NOIP2024加赛6
1.高一上十一月上旬日记2.NOIP2024加赛13.多校A层冲刺NOIP2024模拟赛184.NOIP2024加赛25.多校A层冲刺NOIP2024模拟赛196.多校A层冲刺NOIP2024模拟赛207.NOIP2024(欢乐)加赛38.高一上十一月中旬日记9.NOIP2024加赛410.多校A层冲刺NOIP2024模拟赛2111.2025--炼石计划-- 11 月 13 日 --NOIP 模拟赛 #2012.NOIP2024加赛5
13.NOIP2024加赛6
14.多校A层冲刺NOIP2024模拟赛2415.高一上十一月下旬日记16.多校A层冲刺NOIP2024模拟赛2517.NOIP2024加赛718.2025--炼石计划-- 11 月 23 日 --NOIP 模拟赛 #2319.【MX-S7】梦熊 NOIP 2024 模拟赛 3 & SMOI Round 2(同步赛)20.多校A层冲刺NOIP2024模拟赛2621.NOIP2024加赛822.多校A层冲刺NOIP2024模拟赛27终结篇NOIP2024加赛6
P323. 草莓
-
部分分
- 先将
降序排序,状态转移方程为 ,边界为 ,最终有 即为所求。 - 若费用提前计算则需要将
升序排序并做前缀和,状态转移方程为 ,边界为 ,最终有 即为所求。
- 先将
点击查看代码
ll x[200010],y[200010],f[2][200010]; int main() { #define Isaac #ifdef Isaac freopen("guiltiness.in","r",stdin); freopen("guiltiness.out","w",stdout); #endif ll n,m,i,j; cin>>n>>m; n--; m--; for(i=1;i<=n;i++) { cin>>x[i]; } for(i=1;i<=m;i++) { cin>>y[i]; } sort(x+1,x+n+1); sort(y+1,y+m+1); for(i=1;i<=n;i++) { x[i]+=x[i-1]; } for(i=1;i<=m;i++) { y[i]+=y[i-1]; } memset(f,0x3f,sizeof(f)); f[0][0]=0; for(i=0;i<=n;i++) { for(j=0;j<=m;j++) { f[(i+1)&1][j]=0x3f3f3f3f3f3f3f3f; } for(j=0;j<=m;j++) { f[(i+1)&1][j]=min(f[(i+1)&1][j],f[i&1][j]+y[j]); f[i&1][j+1]=min(f[i&1][j+1],f[i&1][j]+x[i]); } } cout<<f[n&1][m]+x[n]+y[m]<<endl; return 0; }
-
正解
- 上述做法因为需要求解在网格图上的最短路,只能另寻他法。
- 考虑临项交换,观察到最终操作序列上相邻的
交换成 更优当且仅当 ,将 放到一起降序排序即可。
点击查看代码
ll cnt[2]; vector<pair<ll,ll> >a; int main() { #define Isaac #ifdef Isaac freopen("guiltiness.in","r",stdin); freopen("guiltiness.out","w",stdout); #endif ll n,m,x,ans=0,i; cin>>n>>m; n--; m--; for(i=1;i<=n+m;i++) { cin>>x; a.push_back(make_pair(x,i>n)); } sort(a.begin(),a.end()); reverse(a.begin(),a.end()); for(i=0;i<a.size();i++) { ans+=a[i].first*(cnt[a[i].second^1]+1); cnt[a[i].second]++; } cout<<ans<<endl; return 0; }
P324. 三色
-
部分分
- 子任务
- 类似 luogu P11233 [CSP-S 2024] 染色 ,设
表示 中第一个与 颜色不同的是 ,第一个与 颜色互不相同的数是 的方案数。转移时分讨 刷表法转移即可。边界为 。 - 当访问到一个限制时及时去除不合法状态。
- 最终有
即为所求。 - 时间复杂度为
。
- 类似 luogu P11233 [CSP-S 2024] 染色 ,设
点击查看代码
const int p=1000000007; int f[2][5010][5010]; vector<pair<int,int> >q[5010]; int main() { #define Isaac #ifdef Isaac freopen("color.in","r",stdin); freopen("color.out","w",stdout); #endif int t,n,m,l,r,x,ans,lj,lk,rj,rk,i,j,k,h,v; scanf("%d",&t); for(v=1;v<=t;v++) { ans=0; cin>>n>>m; for(i=1;i<=n;i++) { q[i].clear(); } for(i=1;i<=m;i++) { scanf("%d%d%d",&l,&r,&x); q[r].push_back(make_pair(l,x)); } memset(f,0,sizeof(f)); f[1][0][0]=3; for(i=1;i<=n;i++) { lj=lk=0; rj=rk=0x3f3f3f3f; for(j=0;j<q[i].size();j++) { switch(q[i][j].second) { case 1: rj=min(rj,q[i][j].first-1); break; case 2: lj=max(lj,q[i][j].first); rk=min(rk,q[i][j].first-1); break; case 3: lk=max(lk,q[i][j].first); break; default: break; } } for(j=0;j<=i;j++) { for(k=0;k<=max(0,j-1);k++) { if(j<lj||j>rj||k<lk||k>rk) { f[i&1][j][k]=0; } f[(i+1)&1][j][k]=0; } } for(j=0;j<=i-1;j++) { for(k=0;k<=max(0,j-1);k++) { f[(i+1)&1][j][k]=(f[(i+1)&1][j][k]+f[i&1][j][k])%p; f[(i+1)&1][i][k]=(f[(i+1)&1][i][k]+f[i&1][j][k])%p; f[(i+1)&1][i][j]=(f[(i+1)&1][i][j]+f[i&1][j][k])%p; } } } for(j=0;j<=n-1;j++) { for(k=0;k<=max(0,j-1);k++) { ans=(ans+f[n&1][j][k])%p; } } cout<<ans<<endl; } return 0; }
- 子任务
-
正解
- 仍考虑 luogu P11233 [CSP-S 2024] 染色 的优化方式,将
看做矩阵。当 转移到 时,分讨 分别对应复制到 处/将每列累加到 行的对应位置/将每行累加到 列的对应位置。前者直接滚动数组继承,后两者可以看做新加入一行/列。考虑维护每一行、每一列的前缀和。 - 遇到限制时等价于保留合法矩阵,将不合法状态置零。
- 发现处理完限制后保留的都是一个区间,使用
deque
维护合法状态即可,使得每个数仅被加入、删除 次。 - 时间复杂度为
。
点击查看代码
const int p=1000000007; int s[5010],lj[5010],rj[5010],lk[5010],rk[5010],sh[5010],sl[5010],f[5010][5010]; deque<int>q[5010]; void del(int j,int l,int r) { while(q[j].empty()==0&&q[j].front()<l) { sh[j]=(sh[j]-f[j][q[j].front()]+p)%p; sl[q[j].front()]=(sl[q[j].front()]-f[j][q[j].front()]+p)%p; q[j].pop_front(); } while(q[j].empty()==0&&q[j].back()>r) { sh[j]=(sh[j]-f[j][q[j].back()]+p)%p; sl[q[j].back()]=(sl[q[j].back()]-f[j][q[j].back()]+p)%p; q[j].pop_back(); } } int main() { #define Isaac #ifdef Isaac freopen("color.in","r",stdin); freopen("color.out","w",stdout); #endif int t,n,m,l,r,x,ans,i,j,k,v; scanf("%d",&t); for(v=1;v<=t;v++) { scanf("%d%d",&n,&m); ans=0; for(i=0;i<=n;i++) { lj[i]=lk[i]=0; rj[i]=rk[i]=i-1; sh[i]=sl[i]=0; q[i].clear(); for(j=0;j<=max(0,i-1);j++) { q[i].push_back(j); } for(j=0;j<=n;j++) { f[i][j]=0; } } for(i=1;i<=m;i++) { scanf("%d%d%d",&l,&r,&x); switch(x) { case 1: rj[r]=min(rj[r],l-1); break; case 2: lj[r]=max(lj[r],l); rk[r]=min(rk[r],l-1); break; case 3: lk[r]=max(lk[r],l); break; default: break; } } f[0][0]=sh[0]=sl[0]=3; for(i=1;i<=n;i++) { for(j=0;j<=i-1;j++) { if(lj[i]<=j&&j<=rj[i]) { del(j,lk[i],rk[i]); } else { del(j,j+1,0);//全部清空 } } if(i!=n) { for(k=0;k<=i-1;k++) { f[i][k]=(sh[k]+sl[k])%p; sh[i]=(sh[i]+f[i][k])%p; sl[k]=(sl[k]+f[i][k])%p; } } } for(i=0;i<=n;i++) { ans=(ans+sh[i])%p; } printf("%d\n",ans); } return 0; }
- 仍考虑 luogu P11233 [CSP-S 2024] 染色 的优化方式,将
P325. 博弈
-
选出的三个数为
时,有Madeline
必胜。- 若
关于 对称,那么Madeline
直接操作 使其等于 即可获胜。 - 否则,以
为例( 同理)。若在进入该状态后Badeline
必胜,则Madeline
直接仿照原Badeline
的操作方式操作(多操作几步使其到达Badeline
必胜的第一步情况)即可获胜;否则因为Badeline
必败,故Madeline
必胜。
- 若
-
选出的三个数中有两个数相同时,以
为例。此时Madeline
只能将 操作成 (如果无法操作必败),Badeline
继续这种操作方式。若 最低位的 是第偶数位Madeline
必胜,即__builtin_ffs(abs(a-b))%2==0
。 -
选出的三个数都相同时
Madeline
必败。 -
将
倒着插入 树上统计叶子个数即可。点击查看代码
unordered_map<ll,ll>vis; unordered_map<ll,ll>::iterator it; struct Trie { int son[30000010][4],siz[30000010],rt_sum=1; void clear() { for(int i=1;i<=rt_sum;i++) { son[i][0]=son[i][1]=son[i][2]=son[i][3]=siz[i]=0; } rt_sum=1; } int build_rt() { rt_sum++; return rt_sum; } void insert(ll s) { int x=1; for(int i=0;i<=60;i+=2) { if(son[x][(s>>i)&3]==0) { son[x][(s>>i)&3]=build_rt(); } siz[x]++; x=son[x][(s>>i)&3]; } siz[x]++; } ll query(ll s) { int x=1; ll ans=0; for(int i=0;i<=60;i+=2) { ans+=(siz[son[x][((s>>i)&3)^1]]+siz[son[x][((s>>i)&3)^3]]); x=son[x][(s>>i)&3]; } return ans; } }T; int main() { #define Isaac #ifdef Isaac freopen("game.in","r",stdin); freopen("game.out","w",stdout); #endif ll t,n,x,ans,i,j; scanf("%lld",&t); for(j=1;j<=t;j++) { T.clear(); vis.clear(); scanf("%lld",&n); ans=n*(n-1)*(n-2)/6; for(i=1;i<=n;i++) { scanf("%lld",&x); T.insert(x); vis[x]++; } for(it=vis.begin();it!=vis.end();it++) { ans-=it->second*(it->second-1)/2*T.query(it->first); ans-=it->second*(it->second-1)*(it->second-2)/6; } printf("%lld\n",ans); } return 0; }
P326. 后缀数组
-
原题: CodeChef TASUFFIX-Very Long Suffix Array
点击查看 std 代码
#include<iostream> #include<stdio.h> #include<ctype.h> #include<random> #include<map> #include<math.h> #define ll long long #define ld long double #define fi first #define se second #define pii pair<int,int> #define lowbit(x) ((x)&-(x)) #define popcount(x) __builtin_popcount(x) #define inf 0x3f3f3f3f #define infll 0x3f3f3f3f3f3f3f3f #define umap unordered_map #define all(x) x.begin(),x.end() #define mk make_pair #define pb push_back #define ckmax(x,y) x=max(x,y) #define ckmin(x,y) x=min(x,y) #define rep(i,l,r) for(int i=l;i<=r;++i) #define per(i,r,l) for(int i=r;i>=l;--i) #define N 100005 using namespace std; inline int read(){ int x=0,f=0; char ch=getchar(); while(!isdigit(ch)) f|=(ch==45),ch=getchar(); while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return f?-x:x; } const int mo=998244353; inline void red(int &x){x>=mo?x-=mo:0;} inline int qpow(int x,int b){ int res=1; for(;b;x=1LL*x*x%mo,b>>=1) if(b&1) res=1LL*res*x%mo; return res; } struct FHQ{ int ls,rs,sze,cnt,sum,lazy; pii v; }T[N*2]; int rt,pool; mt19937 rnd(114514); inline int newNode(int l,int r){ T[++pool].sze=1,T[pool].cnt=T[pool].sum=max(r-l+1,l-r+1),T[pool].v={l,r}; return pool; } inline void pushup(int k){ T[k].sze=T[T[k].ls].sze+T[T[k].rs].sze+1; T[k].sum=T[T[k].ls].sum+T[T[k].rs].sum+T[k].cnt; } inline void pushdown(int k){ if(!T[k].lazy) return; T[k].lazy=0; swap(T[T[k].ls].v.fi,T[T[k].ls].v.se); swap(T[T[k].rs].v.fi,T[T[k].rs].v.se); swap(T[T[k].ls].ls,T[T[k].ls].rs); swap(T[T[k].rs].ls,T[T[k].rs].rs); T[T[k].ls].lazy^=1; T[T[k].rs].lazy^=1; } int U; void split(int k,int &x,int &y,int s){ if(!k) return (void)(x=y=0); pushdown(k); if(T[T[k].ls].sum+T[k].cnt<=s){ x=k; split(T[k].rs,T[k].rs,y,s-T[T[k].ls].sum-T[k].cnt); U+=T[T[k].ls].sum+T[k].cnt; } else{ y=k; split(T[k].ls,x,T[k].ls,s); } pushup(k); } int merge(int x,int y){ if(!x || !y) return x+y; pushdown(x),pushdown(y); if(rnd()%(T[x].sze+T[y].sze)<T[x].sze){ T[x].rs=merge(T[x].rs,y); pushup(x);return x; } else{ T[y].ls=merge(x,T[y].ls); pushup(y);return y; } } int n,m; pii b[2*N]; void get(int k){ pushdown(k); if(T[k].ls) get(T[k].ls); b[++m]=T[k].v; if(T[k].rs) get(T[k].rs); } map<int,int> rk; signed main(){ freopen("sa.in","r",stdin); freopen("sa.out","w",stdout); n=read(),m=read(); rt=newNode(1,n); for(int i=1;i<=m;++i){ int op=read(),l=read(),r=read(); int x,y,z; U=0; split(rt,x,y,l-1); U=l-1-U; if(U){ int now=y; while(T[now].ls){ pushdown(now); T[now].sum-=U; now=T[now].ls; } T[now].sum-=U,T[now].cnt-=U; if(T[now].v.fi<=T[now].v.se){ int mid=T[now].v.fi+U-1; x=merge(x,newNode(T[now].v.fi,mid)); T[now].v.fi=mid+1; } else{ int mid=T[now].v.fi-U+1; x=merge(x,newNode(T[now].v.fi,mid)); T[now].v.fi=mid-1; } } U=0; split(y,y,z,r-l+1); U=(r-l+1)-U; if(U){ int now=z; while(T[now].ls){ pushdown(now); T[now].sum-=U; now=T[now].ls; } T[now].sum-=U,T[now].cnt-=U; if(T[now].v.fi<=T[now].v.se){ int mid=T[now].v.fi+U-1; y=merge(y,newNode(T[now].v.fi,mid)); T[now].v.fi=mid+1; } else{ int mid=T[now].v.fi-U+1; y=merge(y,newNode(T[now].v.fi,mid)); T[now].v.fi=mid-1; } } if(op==0){ rt=merge(y,merge(x,z)); } else{ swap(T[y].v.fi,T[y].v.se); swap(T[y].ls,T[y].rs); T[y].lazy^=1; rt=merge(x,merge(y,z)); } } m=0; get(rt); // for(int i=1;i<=m;++i) fprintf(stderr,"%d %d\n",b[i].fi,b[i].se); int pre=0; for(int i=1;i<=m;++i){ rk[b[i].fi]=pre+1; pre+=abs(b[i].fi-b[i].se)+1; rk[b[i].se]=pre; } int ans=-1,lst=-1; pre=0; for(int i=1;i<=m;++i){ if(b[i].fi<=b[i].se){ if(b[i].fi!=b[i].se){ if(pre+2>lst) ans++; } else if(rk[b[i].fi+1]>lst) ans++; pre+=b[i].se-b[i].fi+1; if(b[i].fi!=b[i].se){ if(rk[b[i].se+1]>pre) ans++; } lst=rk[b[i].se+1]; } else{ if(rk[b[i].fi+1]>lst) ans++; if(pre+1>rk[b[i].fi+1]) ans++; pre+=b[i].fi-b[i].se+1; lst=pre-1; } ans+=max(0,abs(b[i].fi-b[i].se)-1); } cout<<qpow(2,ans); return 0; }
总结
口胡的费用提前计算一开始想假了,将横竖的边权搞反了。
后记
题面过于狗屎,没有说明行动过程中改变之后的数值仍为整数。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18553208,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】