A题: Array and Peaks
题意:
给定一个 n n n和 k k k,构造一个长度为 n n n的排列,使得排列有 k k k个峰
,满足一个数比它左右相邻的数都大的数就是峰。
题解:
先构造出一个上升的排列,即 1 − n 1-n 1−n升序排列,然后发现,最优的构造方法是,从第二个数开始,每两个数交换便能产生一个峰,即1 3 2 5 4能构造出两个峰。那么只需要按照这种方法去构造,就可以了,特判最后不能构造完。
AC代码:
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
const ll mod=1e9+7;
using namespace std;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b){ll ret=1; while(b){if(b&1)ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret;}
int t,n,k,ans[105];
int main(){
//freopen("testdata.in","r",stdin);
//freopen("testout.out","w",stdout);
cin>>t;
while(t--){
cin>>n>>k;
rep(i,1,n) ans[i]=i;
for(int i=2;i<=n-1;i+=2){
if(k){
swap(ans[i],ans[i+1]);k--;
}else break;
}
if(!k)
rep(i,1,n) cout<<ans[i]<<" ";
else cout<<-1;
cout<<"\n";
}
return 0;
}
/*
*/
B题:AND Sequences
题意:
给定 n n n个非负整数,如果满足对于任意i,满足 a 1 − a i a1-ai a1−ai与运算等于 a i + 1 − a n ai+1-an ai+1−an进行与运算,问满足这样的排列总共多少种?
题解:
考虑i等于1的时候,第一个数等于剩下的所有数进行&运算,那么说所有数&运算就应该等于第一个数,同理,可证i==n-1时也满足。那么说第一个数和最后一个数必须等于所有数&运算出来,先找出有多少个数满足等于所有数&起来,那么对于中间的数(2-(n-1)),就任意排列就可以了。
AC代码:
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
const ll mod=1e9+7;
using namespace std;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b){ll ret=1; while(b){if(b&1)ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret;}
const int N=2e5+5;
int t,n;
ll a[N],ans,cnt,js,jc;
int main(){
//freopen("testdata.in","r",stdin);
//freopen("testout.out","w",stdout);
cin>>t;
while(t--){
cin>>n;
ans=0;js=0;jc=1;
rep(i,1,n) cin>>a[i];
cnt=a[1];
rep(i,2,n) cnt&=a[i];
rep(i,1,n)
if(cnt==a[i]) js++;
if(js<=1){
cout<<0<<"\n";continue;
}
for(ll i=1;i<=n-2;i++) jc=jc*i%mod;
ans=js*(js-1)%mod;
ans=ans*jc%mod;
cout<<ans<<"\n";
}
return 0;
}
/*
*/
C题:Add One
题解:
这题是纯找规律了, d p [ i ] dp[i] dp[i]表示0经过 i i i秒后能产生多少数?
dp[i]=dp[i-9]+dp[i-10]就可以了。
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
const ll mod=1e9+7;
using namespace std;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b){ll ret=1; while(b){if(b&1)ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret;}
const int N=3e5+100;
int t;
ll n,m,ans,a[15],dp[N];
void init(){
rep(i,0,9) dp[i]=1;
for(int i=10;i<N;i++){
dp[i]=(dp[i-9]+dp[i-10])%mod;
}
}
int main(){
//freopen("testdata.in","r",stdin);
//freopen("testout.out","w",stdout);
init();
cin>>t;
while(t--){
scanf("%lld %lld",&n,&m);ans=0;
while(n){
ll tmp=n%10;n/=10;
ans=(ans+dp[m+tmp])%mod;
}
printf("%lld\n",ans);
}
return 0;
}
/*
*/
D题:GCD and MST
题解:
先从最小的点开始,以这个点为min时,向左右两边去找,如果左右两边的数是当前数的倍数,那么就存在这条边,然后并查集维护下,然后修改答案就可以了,初始化答案为p*(n-1)。详见代码
AC代码:
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define pb push_back
const ll mod=1e9+7;
using namespace std;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b){ll ret=1; while(b){if(b&1)ret=ret*a%mod;a=a*a%mod;b>>=1;} return ret;}
const int N=2e5+5;
int t;
ll n,vis[N],a[N],cnt,f[N];
ll p,ans;
struct node{
int pos;
ll a;
}b[N];
bool cmp(node a,node b){
return a.a<b.a;
}
int find(int x){
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
int xx=find(x);
int yy=find(y);
f[xx]=yy;
}
int main(){
//freopen("testdata.in","r",stdin);
//freopen("testout.out","w",stdout);
cin>>t;
while(t--){
scanf("%d %lld",&n,&p);
rep(i,1,n) f[i]=i;
ans=p*(n-1);cnt=n-1;
rep(i,1,n) vis[i]=0;
rep(i,1,n) scanf("%lld",&b[i].a);
rep(i,1,n) a[i]=b[i].a;
rep(i,1,n) b[i].pos=i;
sort(b+1,b+1+n,cmp);
for(int i=1;i<=n;i++){
if(b[i].a>=p) break;
ll l=b[i].pos,r=b[i].pos;
while(l>=1&&!vis[l]){
if(find(l)==find(b[i].pos)&&l!=b[i].pos) break;
if(a[l]%a[b[i].pos]!=0) break;
join(l,b[i].pos);
l--;
}l++;
while(r<=n&&!vis[r]){
if(find(r)==find(b[i].pos)&&r!=b[i].pos) break;
if(a[r]%a[b[i].pos]!=0) break;
join(r,b[i].pos);
r++;
}r--;vis[b[i].pos]=1;
ans-=(p-b[i].a)*min(r-l,cnt);
cnt-=(r-l);
if(cnt<=0) break;
}
printf("%lld\n",ans);
}
return 0;
}
/*
*/
/*
*/
E题待补