A.直接二分长度ck一下区间是否有这些字母即可.
#include <bits/stdc++.h>
using namespace std;
const int N=2e5,M=20;
char s[N];
int pos[M][N];
int C(char c)
{
if(c=='p') return 1;
if(c=='u') return 2;
if(c=='l') return 3;
if(c=='e') return 4;
if(c=='y') return 5;
if(c=='a') return 6;
if(c=='k') return 7;
if(c=='n') return 8;
if(c=='o') return 9;
if(c=='i') return 10;
return 0;
}
bool ck(int p,int len)
{
int flag=1;
for(int i=1;i<=10;i++)
{
if(pos[i][p+len-1]-pos[i][p-1]==0) flag=0;
}
if(flag) return true;
else return false;
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s",s+1);int len=strlen(s+1);
for(int i=1;i<=len;i++)
{
int x=C(s[i]);
for(int j=1;j<=10;j++)
{
pos[j][i]=pos[j][i-1]+(x==j);
}
}
int ans=2e9;
for(int i=1;i<=len;i++)
{
int l=10,r=len-i+1;
while(l<=r)
{
int mid=(l+r)>>1;
if(ck(i,mid))
{
r=mid-1;
ans=min(ans,mid);
}
else l=mid+1;
}
}
for(int i=1;i<=len;i++)
{
for(int j=1;j<=10;j++)
{
pos[j][i]=0;
}
}
ans==2e9?puts("-1"):printf("%d\n",ans);
}
return 0;
}B.套用第一个题,不过这次要二分十次,每次贪心找到最小的即可.边界设置inf.
#include <bits/stdc++.h>
using namespace std;
const int N=2e5,M=20;
char s[N];
vector<int>v[M];
int C(char c)
{
if(c=='p') return 1;
if(c=='u') return 2;
if(c=='l') return 3;
if(c=='e') return 4;
if(c=='y') return 5;
if(c=='a') return 6;
if(c=='k') return 7;
if(c=='n') return 8;
if(c=='o') return 9;
if(c=='i') return 10;
return 0;
}
bool ck(int p,int len)
{
int pos1=p,pos2=p+len-1;
for(int i=2;i<=10;i++)
{
pos1=*lower_bound(v[i].begin(),v[i].end(),pos1);
}
if(pos1<=pos2) return true;
else return false;
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s",s+1);int len=strlen(s+1);
for(int i=1;i<=10;i++) v[i].clear();
for(int i=1;i<=len;i++)
{
int x=C(s[i]);
v[x].push_back(i);
}
for(int i=1;i<=10;i++) v[i].push_back(2e9);
int ans=2e9;
for(int i=1;i<=len;i++)
{
if(s[i]=='p')
{
int l=10,r=len-i+1;
while(l<=r)
{
int mid=(l+r)>>1;
if(ck(i,mid))
{
r=mid-1;
ans=min(ans,mid);
}
else l=mid+1;
}
}
}
ans==2e9?puts("-1"):printf("%d\n",ans);
}
return 0;
}
C.循环节内可过,先预处理出来莫比乌斯函数,然后找循环节,最后输出答案即可.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn =2e7+10;
int prime[maxn],mu[maxn],pcnt;
bool vis[maxn];
void init()
{
mu[1]=1;
for(int i=2;i<maxn;i++)
{
if(!vis[i])
{
prime[++pcnt]=i;
mu[i]=-1;
}
for(int j=1;i*prime[j]<maxn;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=-mu[i];
}
}
}
int main()
{
int T;
cin >>T;
init();
while(T--)
{
ll n,k;
scanf("%lld%lld",&n,&k);
vector<int>v;
map<int,int> vis;
int now=n;
while(!vis[now])
{
v.push_back(now);
vis[now]=1;
now=now+mu[now];
}
int j;
for (int i=0;i<v.size();i++)
if(v[i]==now) {j=i;break;}
vector<int>v1;
for (int i=j;i<v.size();i++)
v1.push_back(v[i]);
if(k<v.size()) cout<<v[k]<<endl;
else cout<<v1[(k-v.size())%v1.size()]<<'\n';
}
return 0;
}D.拿set模拟删边,加边操作,然后最后输出ans即可.
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int u[maxn],v[maxn],a[maxn],op[maxn];
set<int>g[maxn];
int main()
{
int n,cnt=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>op[i];
if(op[i]==3) continue;
cin>>u[i]>>v[i];
a[++cnt]=u[i];
a[++cnt]=v[i];
}
sort(a+1,a+1+cnt);
cnt=unique(a+1,a+1+cnt)-a-1;
for(int i=1;i<=n;i++)
{
if(op[i]==3) continue;
u[i]=lower_bound(a+1,a+1+cnt,u[i])-a;
v[i]=lower_bound(a+1,a+1+cnt,v[i])-a;
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(op[i]==1)
{
if(g[u[i]].count(v[i])) continue;
if(g[u[i]].size()&&g[v[i]].size()) ans--;
else if(!g[u[i]].size()&&!g[v[i]].size()) ans++;
g[u[i]].insert(v[i]);
g[v[i]].insert(u[i]);
}
else if(op[i]==2)
{
if(!g[u[i]].count(v[i])) continue;
g[u[i]].erase(g[u[i]].find(v[i]));
g[v[i]].erase(g[v[i]].find(u[i]));
if(g[u[i]].size()&&g[v[i]].size()) ans++;
else if(!g[u[i]].size()&&!g[v[i]].size()) ans--;
}
else cout<<ans<<endl;
}
return 0;
}
京公网安备 11010502036488号