题意
题解
代码
#include
using namespace std;
void solve() {
int n; cin>>n;
if(n%16) cout<<-1<<'\n';
else cout<<5<<'\n';
}
int main() {
int t=1; //cin>>t;
while(t--) solve();
return 0;
}
题意
题解
打表。逆向思维,求存在gcd为偶数的对立事件,即求事件总数-排列中gcd(ai, i)为奇数恒成立的事件数量。sum=n!,打表可知sub= { A( foolr( (n+1)/2 ) }^2.即res=sum-sub。
证明。如果ai为奇数那么放在哪个位置都可以,因为奇数因子不可能有偶数,所以不管与奇数还是偶数的gcd都不会是偶数;如果是偶数一定是放在奇数位置,才不会出现gcd为偶数。所以对于n讨论
n为奇数时,n+1/2个奇数位置中放n-1/2个偶数和1个奇数。所以gcd全为奇数的情况为
C
n
+
1
2
1
×
(
n
+
1
2
)
!
×
(
n
−
1
2
)
!
=
[
(
n
+
1
2
)
!
]
2
C_{\frac{n+1}{2}}^{1}\times (\frac{n+1}{2})!\times (\frac{n-1}{2})!=[(\frac{n+1}{2})!]^2
C2n+11×(2n+1)!×(2n−1)!=[(2n+1)!]2
n为偶数的情况,gcd全为奇数的情况数量
(
n
2
)
!
×
(
n
2
)
!
=
[
(
n
2
)
!
]
2
(\frac{n}{2})!\times (\frac{n}{2})!=[(\frac{n}{2})!]^2
(2n)!×(2n)!=[(2n)!]2
代码
#include
using namespace std;
const int mod=1e9+7;
int main() {
int n; cin>>n;
int sum=1,sub=1;
for(int i=1;i<=n;i++) sum=1ll*sum*i%mod;
for(int i=1;i<=(n+1)/2;i++) sub=1ll*sub*i%mod;
sub=1ll*sub*sub%mod;
sum=(sum-sub+mod)%mod;
cout<<sum<<'\n';
return 0;
}
题意
题解
代码
#include
using namespace std;
const int mod=1e9+7,N=1e6+5,M=2e6+10;
typedef long long ll;
ll fac[M],infac[M];
ll qmi(ll a,ll b) {
ll res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
void init() {
fac[0]=infac[0]=1;
for(int i=1;i<M;i++) {
fac[i]=fac[i-1]*i%mod;
infac[i]=infac[i-1]*qmi(i,mod-2)%mod;
}
}
ll c(ll a,ll b) {
return fac[a]*infac[b]%mod*infac[a-b]%mod;
}
void solve() {
ll n; cin>>n;
ll res=c(2*n,n);
ll ans=res*qmi(n+1,mod-2)%mod;
res=(res-ans+mod)%mod;
cout<<res<<' '<<ans<<'\n';
}
int main(){
init();
ios::sync_with_stdio(false); cin.tie(0);
int t; cin>>t;
while(t--) solve();
return 0;
}
题意
题解
代码
#include
#include
#include
#include
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N=1e5+10;
int n,m,s,dist[N];
bool vis[N];
vector<PII> g[N];
void add(int u,int v,int w) {
g[u].push_back({v,w});
}
void spfa() {
memset(dist,-1,sizeof dist);
queue<int> q;
q.push(s); vis[s]=1; dist[s]=0x3f3f3f3f;
while(q.size()) {
int u=q.front(); q.pop();
vis[u]=0;
for(auto [v,w]:g[u])
if(dist[v]<min(dist[u],w)) {//min的含义为更新的是此条路径中的最小边权,而<才更新的意思是答案dist[v]求的是所有从s到v的路径中最大值
dist[v]=min(dist[u],w);
if(!vis[v]) q.push(v),vis[v]=1;
}
}
}
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin>>n>>m>>s;
while(m--) {
int u,v,w; cin>>u>>v>>w;
if(u!=v) add(u,v,w);
}
spfa();
for(int i=1;i<=n;i++) cout<<(dist[i]==0x3f3f3f3f ? -1:dist[i])<<' ';
return 0;
}