2021.9.5NOIP模拟赛
前言
周末突然被拉到学校模拟
期望得分:60+30+60+60=210pts
实际得分:60+30+60+0=150pts
题解
T1 conv循环卷积
赛时代码:
conv
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f,N = 2e5+10;
int n,a[N],b[N],c[N];
int main()
{
freopen("conv.in","r",stdin);
freopen("conv.out","w",stdout);
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
if(n==1)
{
printf("%d",a[0]+b[0]);
return 0;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
c[i]=max(c[i],a[j]+b[(i-j+n)%n]);
}
printf("%d ",c[i]);
}
return 0;
}
/*
5
3 2 4 7 5
8 9 6 1 0
*/
T2 sum异或平方和
赛时代码:
sum
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f,N = 50005,mod = 1e9+7;
ll a[N],ans;
int n;
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
(ans+=(a[i]^a[j])%mod*(a[i]^a[j])%mod)%=mod;
}
printf("%lld",ans);
return 0;
}
T3 dis
赛时代码:
dis
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f,N = 1e5+10;
int n,m;
map<int,map<int,bool> > del;
int head[N<<1],ecnt=-1;
ll dp[N][43],g[N][43];
ll ans,sum[43];
struct edge
{
int nxt,to;
}a[N<<1];
void add(int x,int y)
{
a[++ecnt].nxt=head[x];
a[ecnt].to=y;
head[x]=ecnt;
}
//无删边
void dfs1(int u,int fa)
{
dp[u][0]=1;
for(int i=head[u];~i;i=a[i].nxt)
{
int v=a[i].to;
if(v==fa) continue;
dfs1(v,u);
for(int j=1;j<=40;j++)
dp[u][j]+=dp[v][j-1];
}
}
void dfs2(int u,int fa)
{
//g[u][0]=1;
for(int i=head[u];~i;i=a[i].nxt)
{
int v=a[i].to;
if(v==fa) continue;
for(int j=1;j<=40;j++)
g[v][j]+=g[u][j-1]+dp[u][j-1]-dp[v][j-2];
dfs2(v,u);
}
}
//纯暴力
void dfsl(int u,int fa,int now,int dis,int x)
{
//for(int i=1;i<=19;i++) f[u][i]=f[f[u][i-1]][i-1];
for(int i=head[u];~i;i=a[i].nxt)
{
int v=a[i].to;
if(v==fa||del[v][u]) continue;
// f[v][0]=u;
if(dis<=x)
{
if(v>now)
{
//printf("%d->%d\n",now,v);
ans++;
}
if(dis<x) dfsl(v,u,now,dis+1,x);
}
}
}
int main()
{
freopen("dis.in","r",stdin);
freopen("dis.out","w",stdout);
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++)
add(i,i/2),add(i/2,i);
if(n<=110)
{
while(m--)
{
char op[3];
int x;ans=0;
scanf("%s%d",op,&x);
if(op[0]=='?')
{
for(int i=1;i<=n;i++)
dfsl(i,-1,i,1,x);
printf("%lld\n",ans);
}
else del[x][x>>1]=del[x>>1][x]=1;
}
}
else
{
dfs1(1,-1);
dfs2(1,-1);
for(int j=1;j<=40;j++)
{
sum[j]=sum[j-1];
for(int i=1;i<=n;i++)
sum[j]+=dp[i][j]+g[i][j];
}
while(m--)
{
char op[3];
int x;
scanf("%s%d",op,&x);
if(op[0]=='?')
printf("%lld\n",sum[x]>>1);
}
}
return 0;
}
/*
5 5
? 2
- 2
? 2
- 5
? 2
*/
T4 num数字分组
赛时代码:
num
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f,N = 75;
int used[N],flag;
map<int,bool> vis[N];
int n,k,a[N],ans=INF,cnt,maxx=-INF,minx=INF;
#define m (n/k)
void dfs(int stp,int sum,int minn,int maxn)
{
if(cnt>4e7&&n>20)return;
// for(int i=1;i<stp;i++)printf(" ");printf("stp=%d,sum=%d , minn[%d],maxn[%d] (bel=%d)\n",stp,sum,minn,maxn,(stp-1)/m);
// for(int i=1;i<stp;i++)printf(" ");for(int i=1;i<=n;i++)printf("%d ",used[i]);puts("");
if(stp==n+1) {ans=min(ans,sum);return;}
if(sum>ans) return;
cnt++;
for(int i=1;i<=n;i++)
{
if(used[i]||vis[(stp-1)/m][a[i]]) continue;
used[i]=stp,vis[(stp-1)/m][a[i]]=1;
if(!(stp%m))//%m不是%k
dfs(stp+1,sum+max(maxn,a[i])-min(minn,a[i]),INF,-INF);
else
dfs(stp+1,sum,min(minn,a[i]),max(maxn,a[i]));
used[i]=0,vis[(stp-1)/m][a[i]]=0;
}
}
int main()
{
//freopen("num.in","r",stdin);
//freopen("num.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),
maxx=max(a[i],maxx),minx=min(minx,a[i]);
if(k==1)
{
printf("%d",maxx-minx);
return 0;
}
if(k==n)
{
printf("0\n");
return 0;
}
dfs(1,0,INF,-INF);
printf("%d",ans);
return 0;
}
/*
input1
4 2
1 2 1 4
input2
8 4
6 3 8 1 3 1 2 2
*/