2022牛客寒假算法基础集训营 4 全部题解
Posted quinn18
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022牛客寒假算法基础集训营 4 全部题解相关的知识,希望对你有一定的参考价值。
文章目录
- A R 模拟
- B 进制 线段树
- C 蓝彗星 前缀和
- D 雪色光晕 计算几何
- E 真假签到题 签到
- F 小红的记谱法 模拟
- G 子序列权值乘积 数学
- H 真真真真真签到题 签到
- I 爆炸的符卡洋洋洒洒 背包dp
- J 区间合数的最小公倍数 数学
- K 小红的真真假假签到题题 签到
- L 在这冷漠的世界里光光哭哭 dp【待补】
- 总结
比赛链接
题解https://ac.nowcoder.com/discuss/835616?type=101&channel=-1&source_id=0
A R 模拟
题目链接
题意:
给一个包含只包含大写字母的字符串,找有多少个子串包含
k
k
k 个
R
R
R 字符且不包含
P
P
P 字符
题解:
不包括
P
P
P 就分段来计算
至少包含
k
k
k 个
R
R
R
贡献就等于这个位置 第前 k 个
R
R
R 位置
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int a[N], p[N];
signed main()
int n, k; cin>>n>>k;
string s; cin>>s;
s=s+"P";
int cnt=0;
a[0]=-1;
for (int i=0; i<=n; i++)
if(s[i]=='P') a[++cnt]=i;
int ans=0;
for(int j=1; j<=cnt; j++)
int cntt=0;
p[0]=0;
for (int i=a[j-1]+1; i<a[j]; i++)
if (s[i]=='R') p[++cntt]=i+1-a[j-1]-1;
if(cntt>=k) ans+=p[cntt-k+1];
cout<<ans<<endl;
return 0;
B 进制 线段树
题目链接
题意:
题解:
所能表示的某进制的最小值的某进制就是该串里的最大的数字+1,不然那个数不可能出现
题目要求单点修改和区间查询
那就是最简单的求最大值和求和的线段树板子
求和的线段树是存了2-10进制棵每一位的数字 * 该位权值
比如10进制树 123存的是1 * 10 * 10 ------- 2*10 -------3
求和出来还要除与多的权值 取[1,2] ,答案等于120/10
这个求和的bug真的找了一万年呜呜呜
#include<bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;
const int N=1e5+5;
const int M=1e9+7;
int a[N];
int b[13][N];
int n, q;
int p[13][N];
int maxx[4*N];
int sum[13][4*N];
ll ksm(ll a,ll p)ll res=1;while(p)if(p&1)res=res*a%M;a=a*a%M;p>>=1;return res;
void pushup(int id)
maxx[id] = max(maxx[id << 1], maxx[id << 1 | 1]);
void build(int id, int l, int r)
if (l == r)
maxx[id] = a[l];
return;
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
pushup(id);
void update(int id, int l, int r, int x, int v)
if (l == r)
maxx[id] = v;
return;
int mid = (l + r) >> 1;
if (x <= mid)
update(id << 1, l, mid, x, v);
else
update(id << 1 | 1, mid + 1, r, x, v);
pushup(id);
int query(int id, int l, int r, int x, int y)
if(x<=l&&r<=y)
return maxx[id];
int mid=(l+r)>>1;
int ans=0;
if(x<=mid)
ans=max(ans, query(id<<1, l, mid, x, y));
if(y>mid)
ans=max(ans, query(id<<1|1, mid+1, r, x, y));
return ans;
void pushup1(int id, int jin)
sum[jin][id] = (sum[jin][id << 1]+sum[jin][id << 1 | 1])%M;
void build1(int id, int l, int r, int jin)
if (l == r)
sum[jin][id] = b[jin][l]%M;
return;
int mid = (l + r) >> 1;
build1(id << 1, l, mid, jin);
build1(id << 1 | 1, mid + 1, r, jin);
pushup1(id, jin);
void update1(int id, int l, int r, int x, int v, int jin)
if (l == r)
sum[jin][id] = v%M;
return;
int mid = (l + r) >> 1;
if (x <= mid)
update1(id << 1, l, mid, x, v,jin);
else
update1(id << 1 | 1, mid + 1, r, x, v,jin);
pushup1(id, jin);
int query1(int id, int l, int r, int x, int y,int jin)
if(x<=l&&r<=y)
return sum[jin][id]%M;
int mid=(l+r)>>1;
int ans=0;
if(x<=mid)
ans=ans%M+query1(id<<1, l, mid, x, y,jin)%M;
if(y>mid)
ans=ans%M+query1(id<<1|1, mid+1, r, x, y,jin)%M;
ans%=M;
return ans;
signed main()
cin>>n>>q;
string s;
cin>>s;
s='.'+s;
for(int i=n; i>=1; i--)
a[i]=(s[i]-'0');
for(int i=n; i>=1; i--)
for(int j=2; j<=10; j++)
b[j][i]=a[i]*ksm(j, n-i)%M;
//cout<<i<<" "<<j<<" "<<b[j][i]<<endl;
build(1, 1, n);
for(int i=2; i<=10; i++) build1(1, 1, n, i);
//cout<<"$$$"<<query1(1,1,n,1 ,3, 10)<<endl;
while(q--)
int op, x, y;
cin>>op>>x>>y;
if(op==1)
update(1, 1, n, x, y);
for(int i=2; i<=10; i++) update1(1, 1, n, x, y*ksm(i, n-x), i);
else
int dang=query(1, 1, n, x, y);
if(dang==0) cout<<0<<endl;
else
dang++;
cout<<query1(1,1,n,x, y,dang)%M*ksm(ksm(dang, n-y), M-2)%M<<endl;//逆元
return 0;
C 蓝彗星 前缀和
题目链接
题意:
题解:
前缀和求覆盖次数
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int a[N], b[N], c[N];
signed main()
int n, t;
cin>>n>>t;
string s;
cin>>s;
s='.'+s;
for(int i=1; i<=n; i++)
int x; cin>>x;
if(s[i]=='B') b[x]++, b[x+t]--;//x和x+t-1+1
else c[x]++, c[x+t]--;
for(int i=1; i<=N; i++)
b[i]+=b[i-1];
c[i]+=c[i-1];
//cout<<i<<" "<<b[i]<<" "<<c[i]<<endl;输出就可以看到这个时间 彗星亮了没
int ans=0;
for(int i=1; i<=N; i++)
if(b[i]&&!c[i]) ans++;
cout<<ans<<endl;
return 0;
D 雪色光晕 计算几何
题目链接
题意:
题解:
求点到线段的最短距离板子
#include<bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;
const int N=2e5+5;
const int M=1e9+7;
double dis(double xx, double yy, double x1, double y2)
return sqrt((xx-x1)*(xx-x1)+(yy-y2)*(yy-y2));
double Pd(double x, double y, double x1, double y1, double x2, double y2)
double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
if (cross <= 0) return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (cross >= d2) return sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
double r = cross / d2;
double px = x1 + (x2 - x1) * r;
double py = y1 + (y2 - y1) * r;
return sqrt((x - px) * (x - px) + (py - y) * (py - y));
signed main()
int n;
cin>>n;
double x0, y0, X, Y;
cin>>x0>>y0>>X>>Y;
double minn=dis(x0,y0,X,Y);
for(int i=1; i<=n; i++)
double x, y;
cin>>x>>y;
minn=min(minn, Pd(X, Y, x0以上是关于2022牛客寒假算法基础集训营 4 全部题解的主要内容,如果未能解决你的问题,请参考以下文章