当前位置: 首页 > news >正文

CSP-S模拟31

CSP-S模拟31

A. 远征 (expedition)

简单题,直接大力 \(O(nV)\) 预处理 对于每个数每个位置 记录这个数下一个会被更改的位置。

查询直接跳即可,复杂度是 \(O(\log V)\)

Code:

#include<bits/stdc++.h>using namespace std;inline int read()
{int x=0,c=getchar_unlocked();for(;c>'9'||c<'0';c=getchar_unlocked());for(;c>='0'&&c<='9';c=getchar_unlocked())x=(x<<1)+(x<<3)+(c^48);return x;
}int n;
const int N=5e4+5;
unsigned short nxt[1025][N];
int a[N],b[N];void init()
{for(int col=1;col<1024;col++)for(int i=n,last=n+1;i>=1;i--){nxt[col][i]=last;if((col|a[i])==col) last=i;}
}signed main()
{//expeditionfreopen("expedition.in","r",stdin);freopen("expedition.out","w",stdout);n=read();for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<=n;i++) b[i]=read();init();long long Q=read(),anss=0;while(Q--){int l=read(),r=read(),x=read();long long ans=0;if((x|a[l])==x) ans+=b[l],x^=a[l];l=nxt[x][l];while(l<=r&&x){ans+=b[l];x^=a[l];l=nxt[x][l];}anss^=ans;}cout<<anss;return 0;
}

B. 传送 (teleport)

以为是拦路虎,没想到是水。

显然题目的限制 \(3\) 是废话。

先特判 \(u=v\) (\(ans=0\)) 和 \(u,v\) 不在一个集合内 (\(ans=-1\)) 的情况。

先把题目中给出的四元环(偶环)画出来,发现答案至多为 \(2\)

再手模一个三元环(奇环),发现是强连通的,再尝试加边,发现新图仍强连通。五元环同理,也是强连通的。

得到若一个连通块包含奇环,则答案为 \(1\)

若无奇环,则如果 \(u \to v\) 路径长为偶,则答案为 \(2\)。反之答案为 \(1\)

现在关键问题转化为如何在 \(O(n)\) 复杂度内判断该连通块是否有奇环。(当然你可以直接黑白染色判断。)

我们以惊人的注意力发现(当然你也可以从 \(s=1\) 的部分分得到启发),我们在每个连通块内任选一点跑 bfs(设为 \(S\)),记录 \(S\) 到该连通块内的每一个点 \(x\) 的路径 (\(S \to x\)) 长是否可以是偶数 / 奇数。发现若该连通块内存在奇环,则 \(S \to x\) 的路径既有奇长又有偶长。

对于无奇环,发现若 \(u \to v\) 路径长为偶 (\(ans=2\)),则 \(S \to u\)\(S \to v\) 路径长奇偶性相同。反之 \(ans=1\)

做完了。

Code:

#include<bits/stdc++.h>
// #define int long long// #define getchar_unlocked getchar
// #define putchar_unlocked putcharusing namespace std;inline int read()
{int x=0,c=getchar_unlocked();for(;c>'9'||c<'0';c=getchar_unlocked());for(;c>='0'&&c<='9';c=getchar_unlocked())x=(x<<1)+(x<<3)+(c^48);return x;
}// #ifndef ONLINE_JUDGE
// #define ONLINE_JUDGE
// #endifconst int N=1<<20;
int n,m;
vector<int> E[1<<20];
int fa[1<<20];
int find(int x)
{if(x==fa[x]) return x;return fa[x]=find(fa[x]);
}bool vis[N][2];
struct Node{int p,cnt;
};void bfs(int S)
{queue<Node> q;q.push({S,0});vis[S][0]=1;while(q.size()){Node nw=q.front();q.pop();nw.cnt^=1;// cerr<<nw.p<<" "<<nw.cnt<<"\n";for(int to:E[nw.p]){if(vis[to][nw.cnt]) continue;vis[to][nw.cnt]=1;q.push({to,nw.cnt});}}
}int strong[N];signed main()
{// teleport// #ifndef ONLINE_JUDGEfreopen("teleport.in","r",stdin);freopen("teleport.out","w",stdout);// #endifint T=read();n=read();m=read();for(int i=1;i<=n;i++) fa[i]=i;for(int i=1;i<=m;i++){int u=read(),v=read();int fx=find(u),fy=find(v);E[u].push_back(v);E[v].push_back(u);if(fx==fy) continue;fa[fx]=fy;}for(int i=1;i<=n;i++)if(vis[i][0]==0&&vis[i][1]==0) bfs(i);for(int i=1;i<=n;i++)if(vis[i][0]&&vis[i][1]) strong[find(i)]=1;int Q=read();while(Q--){int u=read(),v=read();if(u==v) { putchar_unlocked('0'); }else if(find(u)!=find(v)) { putchar_unlocked('-'); putchar_unlocked('1'); }else if(strong[find(u)]) { putchar_unlocked('1'); }else putchar_unlocked((vis[u][0]^vis[v][0])?('1'):('2'));putchar_unlocked('\n');}return 0;
}

C. 先辈 (anc)

小 Y 定义野兽串是 \(t=114514\)

\(|S|\) 为字符串 \(S\) 的长度。

我们显然有一个 \(O(26^3|S|)\) 的做法,枚举当 \(1,4,5\) 的字符,统计答案。做 nxt 数组优化可做到 \(O(26^3\frac{3|S|}{26})\)。但还是过不了。

具体,设 \(dp[i]\) 表示长度为 \(i\) 一共有多少种情况。
转移也非常显然。
显然 \(dp\) 数组只需要开到 \(7\) 就够了。

考虑发现一些性质。

发现 \(5\) 出现至多 \(1\) 次。考虑不枚举 \(5\) 表示的字符,只枚举 \(1\)\(4\)。只限制 \(5\) 不能和 \(1,4\) 相同即可。

转移同上,只修改 \(dp[4]\) 的转移方程。

如果 TLE,减少你的取模量。

Code:

#include<bits/stdc++.h>
// #define int long longusing namespace std;const int N=5e5+5;
int totans=0;
int dp[6];int n;
string s;
short c[N];const int mod=114514;
int cntt=0;
int nxt[N][26];
int poss[N];
int O=0;bool isappear[26];void init()
{n=s.size();for(int col=0;col<26;col++)for(int i=n,last=n+1;i>=0;i--){nxt[i][col]=last;if(col+'a'==s[i-1]) last=i;}for(int i=1;i<=n;i++) c[i]=s[i-1]-'a',isappear[c[i]]=1;
}void dodp(int x,int y)
{int nwwwww=totans;memset(dp,0,sizeof(dp));dp[0]=1;for(int i=0;i<cntt;i++){// cout<<poss[i]<<" "<<c[poss[i]]<<"\n";// O++;long long dt=0;if(i) dt=poss[i]-poss[i-1]-1;dp[4]=(dp[4]+dp[3]*dt)%mod;// dp[4]%=mod;// totans=(totans+dp[5]*dt)%mod;if(c[poss[i]]==x) {dp[5]+=dp[4];dp[2]+=dp[1];dp[1]+=dp[0];dp[1]%=mod;dp[2]%=mod;dp[5]%=mod;}if(c[poss[i]]==y){dp[3]+=dp[2];totans+=dp[5];dp[3]%=mod;totans%=mod;}// for(int j=1;j<=5;j++) cout<<"dp["<<j<<"]="<<dp[j]<<"\n";// cout<<"\n";}// cout<<"\n";// cout<<x+1<<" "<<y+1<<" "<<-(nwwwww-totans)<<"\n\n";// // totans=(totans+dp[5]*(n-poss[cntt-1]))%mod;
}// #define min(a,b,c) a<b&&a<c?a:(b<c?b:c)
// #define max(a,b,c) a>b&&a>c?a:(b>c?b:c)void init(int x,int y)
{if(!isappear[x]) return;if(!isappear[y]) return;// if(!isappear[z]) return;int i=0;poss[0]=min(nxt[0][x],nxt[0][y]);while(poss[i]<=n){// O++;// poss[i+1]=poss[i]+26;poss[i+1]=min(nxt[poss[i]][x],nxt[poss[i]][y]);i++;}cntt=i;dodp(x,y);dodp(y,x);// for(int j=0;j<cntt;j++) poss[j]=c[poss[j]];// dodp(x,y,z);// dodp(x,z,y);// dodp(y,x,z);// dodp(y,z,x);// dodp(z,x,y);// dodp(z,y,x);
}/*void init(int a,int b,int c)
{int i=0;poss[0]=min({nxt[0][a],nxt[0][b],nxt[0][c]});int last=poss[i];while(last<=n){last=min({nxt[last][a],nxt[last][b],nxt[last][c]});poss[i+1]=last;i++;}
}*/signed main()
{// ios::sync_with_stdio(0);freopen("anc.in","r",stdin);freopen("anc.out","w",stdout);cin>>s;init();for(int a=0;a<26;a++)for(int b=a+1;b<26;b++)init(a,b);cout<<totans<<"\n";// cerr<<"O="<<O<<"\n";// #ifndef ONLINE_JUDGE// #endif//mt19937_64 myrand(time(0));return 0;
}

D. 矩阵 (matrix)

数论分块。

Code:

#include<bits/stdc++.h>
#define int long longusing namespace std;const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar()                                                              \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt)     \? EOF                                                                 \: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{int x=0,c=getchar(),f=0;for(;c>'9'||c<'0';f=c=='-',c=getchar());for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+(c^48);return f?-x:x;
}
inline void write(int x)
{if(x<0) x=-x,putchar('-');if(x>9)  write(x/10);putchar(x%10+'0');
}int n,k;
void solve()
{int ans=0;while(n){int w=n/k;int ww=w+1;int kk=n/ww;int t=k-kk;ans+=w*(t*(n-w+n-w*t)/2);n-=w*t;k=kk;}cout<<ans<<"\n";
}signed main()
{freopen("matrix.in","r",stdin);freopen("matrix.out","w",stdout);scanf("%lld%lld",&n,&k);if(k>=n){cout<<(n*(n-1))/2;return 0;}solve();return 0;
}
http://www.hskmm.com/?act=detail&tid=31179

相关文章:

  • Fortran 实现英文数字验证码识别系统
  • 10.14 NOIP 模拟赛 T1. HappyLovelyEveryday!
  • CSP-J 2025 入门级模拟赛 Day6 复盘 B. 罐の水表
  • 10.14每日总结
  • 四边形不等式
  • 20251014 杂题
  • 二叉树的遍历
  • SQL在智能自动化业务场景中的应用 - Irving11
  • 拼接字符串要求字典序最小
  • 高级语言作业第一次随笔
  • C#实现开机自启动应用多种方式
  • 日志|二叉树|110平衡二叉树|111二叉树的最大深度|199二叉树的右视图
  • Chrome在Speedometer 3.1创下历史最高分,为用户节省数百万小时
  • 西电CTF平台——Moectf 2025 WriteUP
  • [笔记]并查集进阶(带权、扩展域、带删除)
  • 20251013 模拟赛 总结
  • 什么是反应式编程 - 详解
  • SDL3和其附属的编译记录
  • Qwen多模态系列模型笔记—Qwen2-VL
  • WPF 调用 ChangeWindowMessageFilterEx 修改指定窗口 (UIPI) 消息筛选器的用户界面特权隔离
  • 实验1 现代C++基础课程
  • 牙科诊所借力AI营销4个月创收13万
  • 10月14日日记
  • P4653 [CEOI 2017] Sure Bet
  • 20251014
  • PHP虚拟主机测试页面
  • 歌词本。 - Slayer
  • 10月14日
  • 使用 Docker 快速搭建 MinIO 文件存储服务
  • 2025.10.14 正睿二十连测