基础数学
例题:轻拍牛头
这题就很基础了吧,不用多说
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,maxx=-1e9;
ll a[int(1e6+9)],tp[int(1e6+9)],cnt[int(1e6+9)];
int main()
{
cin>>n;
for (int i=1;i<=n;i++){
cin>>a[i];
tp[a[i]]++;
maxx=max(maxx,a[i]);
}
for (int i=1;i<=maxx;i++){
if (!tp[i]) continue;
for (int j=i;j<=maxx;j+=i){
if (!tp[j]) continue;
cnt[j]+=tp[i];
}
}
for (int i=1;i<=n;i++){
cout<<cnt[a[i]]-1<<"\n";
}
return 0;
}
例题:Sherlock and His Girlfriend
这题想一想就知道染两种颜色就够了,因为质数和因数分开染肯定是满足题目条件(当一个数是另一个的质因数时两个染的颜色不同)的
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n;
ll hs[int(1e6)+9],pr[int(1e6)+9];
void xxs(){
int cnt=0;
for (int i=2;i<=1000000;i++){
if (!hs[i]){
pr[++cnt]=i;
}
for (int j=1;pr[j]*i<=1000000&&j<=cnt;j++){
hs[i*pr[j]]=true;
if (i%pr[j]==0) break;
}
}
return;
}
int main()
{
xxs();
cin>>n;
if (n==1){
cout<<1<<"\n"<<1;
return 0;
}
if (n==2){
cout<<1<<"\n"<<1<<" "<<1;
return 0;
}
cout<<2<<"\n";
for (ll i=2;i<=n+1;i++){
if (!hs[i]){
cout<<1<<" ";
}
else{
cout<<2<<" ";
}
}
return 0;
}
快速幂
例题:越狱
蛮简单的这题
#include<bits/stdc++.h>
using namespace std;
long long ans1,a,b,mod=100003;
long long qp(long long x,long long y){
long long ans=1;
while(y){
if (y&1){
ans=(ans%mod*x)%mod;
}
y>>=1;
x=x%mod*x%mod;
}
return ans;
}
int main()
{
cin>>a>>b;
ans1=qp(a,b)%mod-a%mod*qp(a-1,b-1)%mod;
if (ans1<0) ans1+=mod;
cout<<ans1;
return 0;
}
//m^n-m*(m-1)^(n-1)
素数相关内容
例题:素数密度
这里有注释直接看就好了,这题跟下一题有关联可以一起看一看
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+9;
int l,r;
double pr[N];//空间压缩成1e6因为r-l<=1e6
bool hs[N];
int xxs(int n){
for (int i=2;i<=sqrt(n);i++){//埃氏筛
if (!hs[i]){
for (int j=i*2;j<=n;j+=i){
hs[j]=true;
}
}
}
int cnt=0;
for (int i=2;i<=n;i++){//记录+统计质数
if (!hs[i]){
pr[++cnt]=i;
}
}
return cnt;
}
int main()
{
int cnt=xxs(50000);
cin>>l>>r;
memset(hs,false,sizeof(hs));
for (int i=1;i<=cnt;i++){//枚举每个质数
//找在区间内第一个i的倍数
//第1种情况l<=第i个质数则j为2*pr[i]
//第2种情况l>pr[i]则j为l/pr[i]上取整*pr[i]
//两种情况打擂台
//利用默认下取整性质所以的向上取整也可写作(l+pr[i]-1)/pr[i]
for (long long j=max(2*pr[i],ceil(l*1.0/pr[i])*pr[i]);j<=r;j+=pr[i]){
hs[j-l]=true;
}
}
int ans=0;
for (long long i=l;i<=r;i++){//找区间内不是合数的就是质数
if (!hs[i-l]&&i!=0&&i!=1){//特判
// cout<<i<<endl;
ans++;
}
}
cout<<ans;
return 0;
}
例题:Prime Distance
简简单单的在区间内筛一遍然后找相邻两个数之间距离再比较就好了,记得不能直接山哦,这份没有注释,有的在上面可以往上翻一翻
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+9;
int l,r;
double pr[N],pri[N];
bool hs[N];
int xxs(){
int cnt=0;
for (int i=2;i<=50000;i++){
if (!hs[i]){
pr[++cnt]=i;
for (int j=i*2;j<=50000;j+=i){
hs[j]=true;
}
}
}
return cnt;
}
int main()
{
int cnt=xxs();
while(cin>>l>>r){
memset(pri,0,sizeof pri);
memset(hs,false,sizeof(hs));
for (int i=1;i<=cnt;i++){
for (long long j=max(2*pr[i],ceil(l*1.0/pr[i])*pr[i]);j<=r;j+=pr[i]){
hs[j-l]=true;
}
}
int ans=0;
for (long long i=l;i<=r;i++){
if (!hs[i-l]&&i!=0&&i!=1){
pri[++ans]=i;
}
}
int minn=1e9,mia,mib;
int maxx=-1e9,maa,mab;
int cnt=0;
bool f=false;
for (int i=1;i<ans;i++){
int b=pri[i+1];
int a=pri[i];
int cz=b-a;
if (a>=l&&a<=r&&b>=l&&b<=r){
f=true;
if (cz<minn){
minn=cz;
mia=a;
mib=b;
}
if (cz>maxx){
maxx=cz;
maa=a;
mab=b;
}
}
}
if (!f){
puts("There are no adjacent primes.");
continue;
}
printf("%d,%d are closest, ",mia,mib);
printf("%d,%d are most distant.\n",maa,mab);
}
return 0;
}
扩展欧几里得
例题:板子exgcd
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll ex(ll a,ll b,ll &x,ll &y){
if (b==0){
x=1;
y=0;
return a;
}
ll d=ex(b,a%b,x,y);
ll t=x;
x=y;
y=t-(a/b)*y;
return d;
}
int main(){
ll t;
ll a,b,c,x,y;
cin>>t;
while(t--){
cin>>a>>b>>c;
ll d=ex(a,b,x,y);
if (c%d){
cout<<-1<<"\n";
continue;
}
x=x*c/d,y=y*c/d;
ll dx=b/d;
ll dy=a/d;
ll lt=ceil(double(1)*(-x+1)/dx),rt=floor(double(1)*(y-1)/dy);
ll minx=((x%dx)+dx)%dx;
if (minx==0) minx=dx;
ll maxy=(c-minx*a)/b;
ll miny=((y%dy)+dy)%dy;
if (miny==0) miny=dy;
ll maxx=(c-miny*b)/a;
ll gs=(maxx-minx)/dx+1;
if (maxx<=0&&maxy<=0){
cout<<minx<<" "<<miny<<"\n";
continue;
}
cout<<gs<<" "<<minx<<" "<<miny<<" "<<maxx<<" "<<maxy<<"\n";
}
return 0;
}
蒟蒻的悲惨经历
一开始写错了调完之后发现还是不对原来是见祖宗了
不要在意背景那些细节