开了场VP,头上充满buff
A
读错题,题意只找一段,wa一发
找到最长的连续子串就好(补0和1001)
#include<bits/stdc++.h>
using namespace std;
int n,ans,a[1005];
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",a+i);
a[n+1]=1001;
int l=0;
for (int i=0;i<=n+1;i++) if (a[i]+1!=a[i+1])
{
ans=max(ans,i-l-1);
l=i+1;
}
printf("%d\n",ans);
}
B
细节错误,wa一发
很显然乘法一次就够,然后不停开方直到每个质因子次数都为1
#include<bits/stdc++.h>
using namespace std;
int n,dif,ans=1,up;
bool vis[1000005];
int op(int up)
{
if (up<2) return 0;
int now=1,ts=0;
for (;now<up;now<<=1,ts++);
if (now!=up) dif=1;
return ts+dif;
}
int main()
{
scanf("%d",&n);
dif=0;
for (int i=2;i<=n;i++) if (!vis[i])
{
if (n%i==0)
{
int tmp=0;
while (n%i==0) n/=i,tmp++;
ans*=i;
if (up!=tmp && up) dif=1;
up=max(up,tmp);
}
for (int j=i;j<=n;j+=i) vis[j]=1;
}
printf("%d %d\n",ans,op(up));
}
C
看漏了01串这个条件,以为是神仙题
区间取数显然先取1后取0,计算一下答案就好
每次一取数就翻倍,可以借助2的幂计算
#include<stdio.h>
using namespace std;
#define N 100005
typedef long long ll;
const int mod=1000000007;
ll pow[N];
int n,q,ans,L,R,tot,root;
struct node{int sum,l,r;}t[N<<1];
void build(int &k,int l,int r)
{
if (!k) k=++tot;
if (l==r)
{
char c;
scanf("%c",&c);
t[k].sum=c-'0';
return;
}
int mid=l+r>>1;
build(t[k].l,l,mid);
build(t[k].r,mid+1,r);
t[k].sum=t[t[k].l].sum+t[t[k].r].sum;
}
void find(int k,int l,int r)
{
if (L<=l && r<=R)
{
ans+=t[k].sum;
return;
}
int mid=l+r>>1;
if (L<=mid) find(t[k].l,l,mid);
if (mid<R) find(t[k].r,mid+1,r);
}
int main()
{
scanf("%d%d\n",&n,&q);
build(root,1,n);
pow[0]=1;
for (int i=1;i<=n;i++) pow[i]=(pow[i-1]<<1)%mod;
while (q--)
{
scanf("%d%d",&L,&R);
ans=0;
find(1,1,n);
printf("%d\n",(pow[ans]-1+(pow[R-L+1-ans]-1)*(pow[ans]-1)+mod)%mod);
}
}
D
卡了一个小时,智商被碾压
对于每个a,x,均有a→ax→-a→-ax→a,贡献为4x
那么对于每个x考虑有几个a就可以算出答案了
#include<bits/stdc++.h>
using namespace std;
#define N 100000
typedef long long ll;
int vis[N+5];
int pri[10000],tot,n;
ll ans;
void dfs(int k)
{
vis[k]=1;
for (int i=1;i<=tot && k*pri[i]<=n;i++) if (!vis[k*pri[i]]) dfs(k*pri[i]);
}
int main()
{
for (int i=2;i<=N;i++) if (!vis[i])
{
pri[++tot]=i;
for (int j=i;j<=N;j+=i) vis[j]=1;
}
scanf("%d",&n);
dfs(2);
for (int i=2;i<=N;i++) vis[i]+=vis[i-1];
for (int i=2;i<=n;i++) ans+=(ll)vis[n/i]*i<<2;
printf("%I64d\n",ans);
}
E
D题卡了一个小时,然后看到E是个数据结构题,内心凉凉
口胡一个做法,按DFN序对点标号值域建立可持久化线段树
每次询问的时候先求出LCA,再随便选一个点,查询LCA下挂的对应子树内含有的询问点(和缺失的询问点)
要么只含有一个询问点,含有点为答案
要么只缺失一个询问点,缺失点为答案
特殊情况:LCA在询问点集内,答案必定是LCA本身
F
没看
UPD:
口胡真爽(口胡了一坨smg玩意
一个点集的LCA只取决于该点集的DFN序最小和最大两个点
分别抠掉算下剩下的答案就好
#include<bits/stdc++.h>
using namespace std;
#define M 131072
#define N 100005
int f[N][19],tot,aim,L,R,dep[N],n,q,mn,mx;
vector<int> e[N];
struct node{int max,min;}t[M<<1];
void dfs(int k,int fa=0)
{
dep[k]=dep[f[k][0]=fa]+1;
for (int i=0;f[k][i];f[k][i+1]=f[f[k][i]][i],i++);
t[M+k-1].max=t[M+k-1].min=++tot;
for (auto v:e[k]) if (v!=fa) dfs(v,k);
}
void fmin(int k,int l,int r)
{
if (t[aim].min<=t[k].min) return;
int mid=l+r>>1;
if (L<=l && r<=R)
{
if (l==r){aim=k;return;}
if (t[k<<1].min==mn) fmin(k<<1,l,mid);
if (t[k<<1|1].min==mn) fmin(k<<1|1,mid+1,r);
return;
}
if (L<=mid) fmin(k<<1,l,mid);
if (mid<R) fmin(k<<1|1,mid+1,r);
}
void fmax(int k,int l,int r)
{
if (t[aim].max>=t[k].max) return;
int mid=l+r>>1;
if (L<=l && r<=R)
{
if (l==r){aim=k;return;}
if (t[k<<1].max==mx) fmax(k<<1,l,mid);
if (t[k<<1|1].max==mx) fmax(k<<1|1,mid+1,r);
return;
}
if (L<=mid) fmax(k<<1,l,mid);
if (mid<R) fmax(k<<1|1,mid+1,r);
}
void get_ex(int k,int l,int r)
{
if (L<=l && r<=R)
{
mn=min(mn,t[k].min);
mx=max(mx,t[k].max);
return;
}
int mid=l+r>>1;
if (L<=mid) get_ex(k<<1,l,mid);
if (mid<R) get_ex(k<<1|1,mid+1,r);
}
inline void get(int l,int r,int &u,int &v)
{
L=l,R=r;
t[aim=0]={n+1,n+1};
mn=n+1;mx=0;
get_ex(1,1,M);
fmin(1,1,M);
u=aim-M+1;
t[aim=0]={0,0};
fmax(1,1,M);
v=aim-M+1;
}
inline int lca(int u,int v)
{
if (dep[u]<dep[v]) swap(u,v);
if (v==0) return u;
if (dep[u]!=dep[v]) for (int i=0;dep[u]-dep[v]>>i;i++) if ((dep[u]-dep[v]>>i)&1) u=f[u][i];
if (u==v) return u;
for (int i=17;~i;i--) if (f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
return f[u][0];
}
inline int find(int l,int r)
{
if (r<l) return 0;
int u,v;
get(l,r,u,v);
return lca(u,v);
}
int main()
{
scanf("%d%d",&n,&q);
for (int i=2,x;i<=n;i++)
{
scanf("%d",&x);
e[x].push_back(i);
}
dfs(1);
for (int k=M-1;k;k--)
{
t[k].max=max(t[k<<1].max,t[k<<1|1].max);
t[k].min=min(t[k<<1].min,t[k<<1|1].min);
}
for (int u,v,p1,p2,L,R;q--;)
{
scanf("%d%d",&L,&R);
get(L,R,u,v);
p1=lca(find(L,u-1),find(u+1,R));
p2=lca(find(L,v-1),find(v+1,R));
if (dep[p1]<dep[p2]) swap(u,v),swap(p1,p2);
printf("%d %d\n",u,dep[p1]-1);
}
}