为了防止以后刷机把代码清空,贴一下赛时的代码和补题后的代码
A.Mocha 上小班啦
签到题
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
if(n > 10){
cout<<"-1\n";
}
else{
if(n == 1)
cout<<"1\n";
else{
int x = 10;
for(int i = 2; i < n; ++ i)
x = x * 10 + i;
printf("%d\n", x);
}
}
return 0;
}
B.Hash
队友王大爹前10分钟就有思路了,奈何他OI习惯加EOF,没有改输入格式,WA了,赛后改了一下输入就A了,有点可惜
#include<iostream>
#include<cstdio>
using namespace std;
const int g=200085,p=998244353;
int a[g],s,t[905];
char c,ch[82];
long long ans,dp[g];
const int N = 2e5 + 10;
char ss[N];
int f(int x,int y)//从x+1到y的hash
{return (a[y]-(long long)a[x]*t[y-x]%p+p)%p;}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0);
// freopen("in","r",stdin);
t[0]=1,t[1]=31;
for(int i=2;i<=902;i++)
t[i]=(long long)t[i-1]*31%p;
scanf("%s",ss);
// printf("%s\n",ss);
for(int i = 0;ss[i];i ++ )
{
a[s+1]=(long long)a[s]*31%p;
s++;
if(s <= 15) ch[s]=ss[i];
if(ss[i]=='a') a[s]++;
if(ss[i]=='e') a[s]+=2;
if(ss[i]=='h') a[s]+=3;
if(ss[i]=='n') a[s]+=4;
}
for(int i=1;i<=min(s,15);i++)
{
a[s+i]=(long long)a[s+i-1]*31%p;
if(ch[i]=='a') a[s+i]++;
if(ch[i]=='e') a[s+i]+=2;
if(ch[i]=='h') a[s+i]+=3;
if(ch[i]=='n') a[s+i]+=4;
}
for(int i=1;i<=min(15,s);i++)
{
dp[i-1]=0;
for(int j=i;j<=i+6;j++)
dp[j]=f(i-1,j);
for(int j=i+7;j<=s+i-1;j++)
{
dp[j]=dp[j-1]+f(j-1,j);
for(int k=max(j-15,i-1);k<j-1;k++)
dp[j]=max(dp[j],dp[k]+f(k,j));
}
ans=max(ans,dp[s+i-1]);
}
printf("%lld",ans);
return 0;
}
C.Serval 的试卷答案
看题解是线段树加组合数学,赛时没开,回头补一下
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
const int mod = 998244353;
char s[N];
int jc[N];
struct node{
int l,r;
int cnt;
int lazy;
node(){l = r = cnt = lazy = 0;}
node(int l,int r,int cnt,int lazy): l(l),r(r),cnt(cnt),lazy(lazy){}
node operator + (const node &a) const{
if(l == 0) return a;
return node{l,a.r,cnt + a.cnt - (r < a.l),0};
}
}tr[N << 2];
void pushup(int rt){
tr[rt] = tr[rt << 1] + tr[rt << 1 | 1];
}
void build(int rt,int l,int r){
if(l == r)
tr[rt] = node{s[l],s[l],1,0};
else{
int mid = (l + r) >> 1;
build(rt << 1,l,mid);
build(rt << 1 | 1,mid + 1,r);
pushup(rt);
}
}
void pushdown(int rt){
if(!tr[rt].lazy) return ;
tr[rt << 1].lazy = (tr[rt].lazy + tr[rt << 1].lazy) % 4;
tr[rt << 1 | 1].lazy = (tr[rt].lazy + tr[rt << 1 | 1].lazy) % 4;
tr[rt << 1].l += tr[rt].lazy;
if(tr[rt << 1].l - 'A' + 1 > 4){
tr[rt << 1].l -= 4;
tr[rt << 1].cnt -= 1;
}
tr[rt << 1].r += tr[rt].lazy;
if(tr[rt << 1].r - 'A' + 1 > 4){
tr[rt << 1].r -= 4;
tr[rt << 1].cnt += 1;
}
tr[rt << 1 | 1].l += tr[rt].lazy;
if(tr[rt << 1 | 1].l - 'A' + 1 > 4){
tr[rt << 1 | 1].l -= 4;
tr[rt << 1 | 1].cnt -= 1;
}
tr[rt << 1 | 1].r += tr[rt].lazy;
if(tr[rt << 1 | 1].r - 'A' + 1 > 4){
tr[rt << 1 | 1].r -= 4;
tr[rt << 1 | 1].cnt += 1;
}
tr[rt].lazy = 0;
}
void update(int rt,int l,int r,int L,int R){
if(l <= L && r >= R){
if(tr[rt].l == 'D') -- tr[rt].cnt;
if(tr[rt].r == 'D') ++ tr[rt].cnt;
if(++ tr[rt].l == 'E') tr[rt].l = 'A';
if(++ tr[rt].r == 'E') tr[rt].r = 'A';
if(++ tr[rt].lazy == 4) tr[rt].lazy = 0;
return ;
}
pushdown(rt);
int mid = (L + R) >> 1;
if(l <= mid) update(rt << 1,l,r,L,mid);
if(r >= mid + 1) update(rt << 1 | 1,l,r,mid + 1,R);
pushup(rt);
}
node query(int rt,int l,int r,int L,int R){
if(l <= L && r >= R){
return tr[rt];
}
else{
pushdown(rt);
int mid = (L + R) >> 1;
node ans;
if(mid >= l) ans = ans + query(rt << 1,l,r,L,mid);
if(mid < r) ans = ans + query(rt << 1 | 1,l,r,mid + 1,R);
return ans;
}
}
int ksm(int x,int y){
int ans = 1;
while(y){
if(y & 1) ans = ans * x % mod;
x = x * x % mod;
y >>= 1;
}
return ans;
}
int inv(int x){
return ksm(x,mod - 2);
}
int C(int x,int y){
if((x < y) || (x < 0) || (y < 0)) return 0;
return jc[x] * inv(jc[x - y]) % mod * inv(jc[y]) % mod;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,q;
cin>>n>>q;
jc[0] = 1;
for(int i = 1;i <= n;i ++ ){
jc[i] = jc[i - 1] * i % mod;
}
cin>>s+1;
build(1,1,n);
while(q -- ){
int op;
cin>>op;
if(op == 1){
int l,r;
cin>>l>>r;
update(1,l,r,1,n);
}
else{
int l,r,k;
cin>>l>>r>>k;
node tt = query(1,l,r,1,n);
cout<<C(r - l + 1 - tt.cnt,k - tt.cnt)<<"\n";
}
}
}
D.Mocha 上中班啦
计算几何,这页直接没看
E.Serval 的俳句
签到题,忘了加等号贡献了第一发WA
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int a[30][N];
vector<int> v1[30],v2[30];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
string s;
cin>>s;
for(int i = 0;s[i];i ++ ){
a[s[i] - 'a'][i + 1] = a[s[i] - 'a'][i] + 1;
for(int j = 0;j < 26;j ++ ){
if(j != s[i] - 'a')
a[j][i + 1] = a[j][i];
}
}
if(n < 17){
cout<<"none\n";
return 0;
}
for(int i = 0;s[i];i ++ ){
v1[s[i] - 'a'].push_back(i + 1);
}
for(int i = n - 1;i >= 0;i -- ){
v2[s[i] - 'a'].push_back(i + 1);
}
for(int i = 0;i < 26;i ++ ){
for(int j = 0;j < 26;j ++ ){
for(int k = 0;k < 26;k ++ ){
if(v1[i].size() >= 5 && v2[j].size() >= 5){
if(v1[i][4] + 7 < v2[j][4]){
if(a[k][v2[j][4] - 1] - a[k][v1[i][4] + 1] >= 7){
for(int kk = 1;kk <= 5;kk ++ )
cout<<char(i + 'a');
for(int kk = 1;kk <= 7;kk ++ )
cout<<char(k + 'a');
for(int kk = 1;kk <= 5;kk ++ )
cout<<char(j + 'a');
cout<<"\n";
return 0;
}
}
}
}
}
}
cout<<"none\n";
return 0;
}
F.集合之和
奇数时很好证明存在,也很容易构造答案,偶数是我跟尤大爹对拍的时候瞎造数据试出来的规律
#include <cstdio>
#define rep(i, a, b) for(int i = (a); (i) <= (b); ++ (i))
int main() {
int n; scanf("%d", &n);
if (n == 2 || n == 4) return puts("-1") & 0;
if (n == 1) return printf("1\n1\n") & 0;
int t = (n + 1) >> 1;
if (n & 1) {
printf("%d\n", t);
rep(i, 1, t)
printf("%d ", i);
puts(""); return 0;
} else {
printf("%d\n", t);
rep(i, 1, t - 1)
printf("%d ", i);
printf("%d\n", t + 1);
return 0;
}
return 0;
}
G.Mocha 上大班啦
假题,可以看出来修改操作根本没有用
#include <cstdio>
#define rep(i, a, b) for(int i = (a); (i) <= (b); ++ (i))
const int N = 1e6 + 5;
const int P = 998244353;
int st[N];
int main() {
int n, m, x; scanf("%d%d", &n, &m);
rep(i, 1, m) st[i] = 1;
rep(i, 1, n) {
rep(j, 1, m) {
scanf("%1d", &x);
st[j] &= x;
}
} int q; scanf("%d", &q);
int i, j, l, r, p;
while (q --) scanf("%d%d%d%d%d", &i, &j, &l, &r, &p);
int cnt = 0; rep(i, 1, m) if (st[i]) ++ cnt;
printf("%d\n", cnt % P);
return 0;
}
H.旋转水管
尤大爹写了个dfs过的
#include <cstdio>
#define rep(i, a, b) for(int i = (a); (i) <= (b); ++ (i))
const int N = 1e6 + 5;
int m, x, y, l[2][N];
bool mp[2][N];
bool dfs(int cx, int cy, int dir) {
if (cx == 2 && cy == y && !dir) return true;
if (cx < 0 || cx > 1 || cy < 1 || cy > m) return false;
if (mp[cx][cy]) return false; mp[cx][cy] = 1;
bool mk = 0;
if (l[cx][cy] == 1) {
if (dir == 0) mk = dfs(cx + 1, cy, 0);
if (dir == 1) mk = dfs(cx - 1, cy, 1);
if (dir == 2) mk = dfs(cx, cy + 1, 2);
if (dir == 3) mk = dfs(cx, cy - 1, 3);
} else {
if (dir == 0) mk = dfs(cx, cy - 1, 3) | dfs(cx, cy + 1, 2);
if (dir == 1) mk = dfs(cx, cy - 1, 3) | dfs(cx, cy + 1, 2);
if (dir == 2) mk = dfs(cx - 1, cy, 1) | dfs(cx + 1, cy, 0);
if (dir == 3) mk = dfs(cx - 1, cy, 1) | dfs(cx + 1, cy, 0);
} if (!mk) mp[cx][cy] = 0;
return mk;
}
int main() {
int t; scanf("%d", &t); while (t --) {
scanf("%d%d%d", &m, &x, &y);
rep(j, 0, 1) rep(i, 1, m) {
char c = getchar(); while (c != 'L' && c != 'I') c = getchar();
l[j][i] = (c == 'L') ? 2 : 1;
} puts(dfs(0, x, 0) ? "YES" : "NO");
rep(j, 1, m) mp[0][j] = mp[1][j] = 0;
}
return 0;
}
I.Oshwiciqwq 的电梯
模拟,赛场时最后四十分钟调的,那个时候没有想到处理一下初始时间以及数组开小了,赛后一会就A了
#include <bits/stdc++.h>
using namespace std;
const int N = 210;
int ttt[N];
struct node{
int t;
int x1,y1,z1;
int x2,y2,z2;
bool xx,yy,zz;
}pe[N];
struct node1{
int ty;
int xx,yy,zz;
}dian[N];
struct ans{
int ti;
int id1;
int id2;
int pos1;
int pos2;
int pos3;
int fg;
};
vector<ans> v;
bool cmp(ans a,ans b){
return (a.ti < b.ti) || (a.ti == b.ti && a.id2 < b.id2) || (a.ti == b.ti && a.id2 == b.id2 && a.fg > b.fg) || (a.ti == b.ti && a.id1 < b.id1 && a.fg == b.fg && a.id2 == b.id2);
}
int n,m,h;
int k,q;
int fuck(int x, int lim) {
x %= lim; if (!x) return lim;
else return x;
}
int dis(int x,int y,int lim){
if(x < y) return y - x;
else{
return lim - x + y;
}
}
bool vis[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
memset(pe,0,sizeof pe);
memset(dian,0,sizeof dian);
cin>>n>>m>>h;
cin>>k;
for(int i = 1;i <= k;i ++ ){
int ty,x,y,z;
cin>>ty>>x>>y>>z;
dian[i] = {ty,x,y,z};
}
cin>>q;
for(int i = 1;i <= q;i ++ ){
int t,x1,y1,z1,x2,y2,z2;
cin>>t>>x1>>y1>>z1>>x2>>y2>>z2;
ttt[i] = t;
if(x1 == x2 && y1 == y2 && z1 == z2)
pe[i] = {t,x1,y1,z1,x2,y2,z2,1,1,1};
else if(x1 == x2 && y1 == y2 && z1 != z2)
pe[i] = {t,x1,y1,z1,x2,y2,z2,1,1,0};
else if(x1 == x2 && y1 != y2 && z1 == z2)
pe[i] = {t,x1,y1,z1,x2,y2,z2,1,0,1};
else if(x1 != x2 && y1 == y2 && z1 == z2)
pe[i] = {t,x1,y1,z1,x2,y2,z2,0,1,1};
else if(x1 == x2 && y1 != y2 && z1 != z2)
pe[i] = {t,x1,y1,z1,x2,y2,z2,1,0,0};
else if(x1 != x2 && y1 == y2 && z1 != z2)
pe[i] = {t,x1,y1,z1,x2,y2,z2,0,1,0};
else if(x1 != x2 && y1 != y2 && z1 == z2)
pe[i] = {t,x1,y1,z1,x2,y2,z2,0,0,1};
else pe[i] = {t,x1,y1,z1,x2,y2,z2,0,0,0};
}
for(int i = 1;i <= 20000;i ++ ){
for(int j = 1;j <= k;j ++ ){
for(int kk = 1;kk <= q;kk ++ ){
if(dian[j].ty == 0 && pe[kk].xx == 0 && i >= ttt[kk]){
// cout<<i<<":"<<kk<<"||||\n";
int nx = fuck(i + dian[j].xx,n);
if(nx == pe[kk].x1 && dian[j].yy == pe[kk].y1 && dian[j].zz == pe[kk].z1 && i >= ttt[kk]){
if(i == ttt[kk] && vis[kk] == 0){
vis[kk] = 1;
v.push_back({i,kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z1,0});
v.push_back({i + dis(pe[kk].x1,pe[kk].x2,n),kk,j,pe[kk].x2,pe[kk].y1,pe[kk].z1,1});
ttt[kk] = i + dis(pe[kk].x1,pe[kk].x2,n);
pe[kk].xx = 1;
pe[kk].x1 = pe[kk].x2;
}
else if(i > ttt[kk]){
v.push_back({i,kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z1,0});
v.push_back({i + dis(pe[kk].x1,pe[kk].x2,n),kk,j,pe[kk].x2,pe[kk].y1,pe[kk].z1,1});
ttt[kk] = i + dis(pe[kk].x1,pe[kk].x2,n);
pe[kk].xx = 1;
pe[kk].x1 = pe[kk].x2;
vis[kk] = 1;
}
}
}
else if(dian[j].ty == 1 && pe[kk].yy == 0 && pe[kk].xx == 1){
int ny = fuck(i + dian[j].yy,m);
if(ny == pe[kk].y1 && dian[j].xx == pe[kk].x1 && dian[j].zz == pe[kk].z1 && i >= ttt[kk]){
if(i == ttt[kk] && vis[kk] == 0){
v.push_back({i,kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z1,0});
v.push_back({i + dis(pe[kk].y1,pe[kk].y2,m),kk,j,pe[kk].x1,pe[kk].y2,pe[kk].z1,1});
ttt[kk] = i + dis(pe[kk].y1,pe[kk].y2,m);
pe[kk].yy = 1;
pe[kk].y1 = pe[kk].y2;
vis[kk] = 1;
}
else if(i > ttt[kk]){
v.push_back({i,kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z1,0});
v.push_back({i + dis(pe[kk].y1,pe[kk].y2,m),kk,j,pe[kk].x1,pe[kk].y2,pe[kk].z1,1});
ttt[kk] = i + dis(pe[kk].y1,pe[kk].y2,m);
pe[kk].yy = 1;
pe[kk].y1 = pe[kk].y2;
vis[kk] = 1;
}
}
}
else if(dian[j].ty == 2 && pe[kk].zz == 0 && pe[kk].xx == 1 && pe[kk].yy == 1){
int nz = fuck(i + dian[j].zz,h);
if(nz == pe[kk].z1 && dian[j].xx == pe[kk].x1 && dian[j].yy == pe[kk].y1 && i >= ttt[kk]){
if(i == ttt[kk] && vis[kk] == 0){
v.push_back({i,kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z1,0});
v.push_back({i + dis(pe[kk].z1,pe[kk].z2,h),kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z2,1});
ttt[kk] = i + dis(pe[kk].z1,pe[kk].z2,h);
pe[kk].zz = 1;
pe[kk].z1 = pe[kk].z2;
vis[kk] = 1;
}
else if(i > ttt[kk]){
v.push_back({i,kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z1,0});
v.push_back({i + dis(pe[kk].z1,pe[kk].z2,h),kk,j,pe[kk].x1,pe[kk].y1,pe[kk].z2,1});
ttt[kk] = i + dis(pe[kk].z1,pe[kk].z2,h);
pe[kk].zz = 1;
pe[kk].z1 = pe[kk].z2;
vis[kk] = 1;
}
}
}
}
}
}
sort(v.begin(),v.end(),cmp);
for(int i = 0;i < v.size();i ++ ){
// cout<<v[i].ti<<"\n";
cout<<"["<<v[i].ti<<"s]"<<" Person "<<v[i].id1<<" ";
if(v[i].fg == 0){
cout<<"IN Elevator "<<v[i].id2<<" at ("<<v[i].pos1<<", "<<v[i].pos2<<", "<<v[i].pos3<<")\n";
}
else if(v[i].fg == 1){
cout<<"OUT Elevator "<<v[i].id2<<" at ("<<v[i].pos1<<", "<<v[i].pos2<<", "<<v[i].pos3<<")\n";
}
}
}
J.Mex Tree
尤大爹一眼就有思路,写了个dfs,码了20分钟不到就给过了
#include <cstdio>
#define rep(i, a, b) for(int i = (a); (i) <= (b); ++ (i))
const int N = 1e6 + 5;
const int M = 3e6 + 5;
struct EDGE {
int nxt, to;
}e[M];
int w[N], id[N], siz[N], head[N], cnt, mn[N];
bool vis[N];
void add(int u, int v) {
e[++ cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
return ;
}
void dfs(int u) {
vis[u] = 1, mn[u] = w[u], siz[u] = 1;
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (vis[v]) continue;
dfs(v); if (mn[v] < mn[u])
mn[u] = mn[v];
siz[u] += siz[v];
}
return ;
}
int main() {
int n, x; scanf("%d", &n);
rep(i, 1, n) scanf("%d", &w[i]), id[w[i]] = i;
rep(i, 2, n) {
scanf("%d", &x);
add(x, i), add(i, x);
} dfs(id[0]);
int mx = 0;
for(int i = head[id[0]]; i; i = e[i].nxt)
if (siz[e[i].to] > mx)
mx = siz[e[i].to];
printf("%d ", mx);
rep(i, 1, n - 1) {
if (mn[id[i]] < i)
printf("0 ");
else printf("%d ", n - siz[id[i]]);
} printf("%d\n", n);
return 0;
}
K.复合函数
基环树,不会
L.串串串串……
压根就没看,完全在能力之外的题
总结:OI大爹还是厉害,如果当时输入格式对的话,估计就能8题了,学弟还是猛,被带飞了捏。