wxy 4.5 牛客练习赛51重现
v>
wxy 4.5 牛客练习赛51重现
5163
A
题目中的子串和现实中的子串也许定义不一样,要注意区分按照题目来。
题解解法:做一个前缀和一个后缀,前缀和sum1[i ]记录位置1...i中a的个数,后缀和sum2[i ]记录i...n
中c的个数。从前往后枚举字符串的所有位置,如果当前位置i的字符串为'b',答案加上sum1[i-
1]*sum2[i+1]即可,时间复杂读O(n )
B
如果时暴力的查找不妨往lower_bound和upper_bound想。
题解做法:设nex[i ] [j ]表示s串中第i后面第一个字符为(j+'a')的位置,规定s串的下表从1开始,如果不
存在这样的位置则nex[i ] [j ]=-1。对于每次查询,按顺序枚举串t的所有在字符,每次优先匹配可以匹配
的最小位置进行贪心。最开始我们设now=0,每次枚举到串t的位置i,我们使得now=nex[now ] [t[i]-'a' ],
如果途中now=-1,说明t不是s的子串,否则t是s的子串。队列辅助,在线性时间内解决。
# include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+100;
char s[MAXN],t[100];
int f[MAXN][30];
queue<int> q[30];
int main()
{
int n,Q; scanf("%d%d",&n,&Q);
scanf("%s",s+1);
for(int i=1;i<=n;++i){
q[s[i]-'a'].push(i);
}
for(int i=0;i<26;++i){
if(!q[i].empty()){
f[0][i]=q[i].front();
}else f[0][i]=-1;
}
for(int i=1;i<=n;++i){
q[s[i]-'a'].pop();
for(int j=0;j<26;++j){
if(!q[j].empty()) f[i][j]=q[j].front();
else f[i][j]=-1;
}
}
while(Q--){
scanf("%s",t+1);
int now=0;
int len=strlen(t+1);
int ff=1;
for(int i=1;i<=len;++i){
now=f[now][t[i]-'a'];
if(now==-1){C
打表找规律,勾股定律
a为奇数的时候,c-b=1 b=(a^2-1)/2 c=(a^2+1)/2;
a为偶数的时候,c-b=2 b=a^2/4-1 c=a^2/4+1
D
正解因该时二分图的最大匹配,还有一种比较假的做法
ff=0;
break;
}
}
if(ff) printf("YES\n");
else printf("NO\n");
}
return 0;
}
# include <bits/stdc++.h>
using namespace std;
const int MAXN=500;
struct Node{
int l,r,len;
}node[MAXN];
vector<int> v[MAXN];
int f[MAXN],vis[MAXN];
int Find(int x)
{
int len=v[x].size();
for(int i=0;i<len;++i){
if(vis[v[x][i]]==0){
vis[v[x][i]]=1;
if(f[v[x][i]]==0||Find(f[v[x][i]])){
f[v[x][i]]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int n,Q; scanf("%d%d",&n,&Q);
for(int i=1;i<=n;++i){
scanf("%d",&node[i].l);
}
for(int i=1;i<=n;++i){
scanf("%d",&node[i].r);
for(int j=node[i].l;j<=node[i].r;++j){
v[j].push_back(i);
}E
思考方向是对的,也是分成几段来算,但是贪心的策略错了。不是要一段越长越好,而是要存在的两端
长度不超过1,中庸之道方为大道啊
二分构造的段数mid,那么a=n/mid,b=b%mid,其中有b段最大值时a+1,有mid-b段的最大值为a,即可
二分
这么简单的题,。。,也没做出来,要摆正心态,好好思考每一道题就好了,不要太紧张,不要太想着
最后会打的好不好,就当作平时在刷题就好了,不要太把比赛当回事。
}
while(Q--){
int l,r; scanf("%d%d",&l,&r);
int ans=0;
memset(f,0,sizeof(f));
for(int i=l;i<=r;++i){
memset(vis,0,sizeof(vis));
if(Find(i)) ans++;
}
printf("%d\n",ans);
}
return 0;
}
# include <bits/stdc++.h>
using namespace std;
int n,m;
int check(int mid)
{
int a=n/mid,b=n%mid;
return (1+a+1)*(a+1)/2*b+(1+a)*a/2*(mid-b)<=m;
}
void solve(int mid)
{
int a=n/mid,b=n%mid;
for(int i=1;i<=b;++i){
for(int j=1;j<=a+1;++j){
printf("%d ",j);
}
}
for(int i=1;i<=(mid-b);++i){
for(int j=1;j<=a;++j){
printf("%d ",j);
}
}
printf("\n");
return ;
}
int main()
{
scanf("%d%d",&n,&m);
int l=1,r=n+1;
while(l<r){F
树链剖分,待补
向wjmzbmr学习,acm本就是逆天而行。
浙公网安备 33010602011771号