img
算法竞赛进阶指南刷题篇之位运算
A.a^b
题目描述
求 a 的 b 次方对 p 取模的值,其中 0≤a,b,p≤109,p>0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<bits/stdc++.h> using namespace std; unsigned long long kmi(unsigned long long a,unsigned long long b,unsigned long long p) { int ans=1; a = a % p; while(b) { if(b&1)ans=ans*a%p; a=a*a%p; b>>=1; } return ans%p; } int main() { unsigned long long a,b,p; cin>>a>>b>>p; cout<<kmi(a,b,p); return 0; }
|
B.Raising Modulo Numbers
分组快速幂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include<iostream> #include<cstdio> using namespace std; typedef unsigned long long int ll; int quick(int a,int b,int c) { int ans=1; a=a%c; while(b!=0) { if(b&1) ans=(ans*a)%c; b>>=1; a=(a*a)%c; } return ans; } int main() { int t; cin>>t; while(t--) { int m,n; int ans=0; cin>>m>>n; for(int i=0;i<n;i++) { int a,b; cin>>a>>b; ans+=quick(a,b,m); ans%=m; } cout<<ans<<endl; } }
|
C.64位整数乘法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<bits/stdc++.h> using namespace std; long long qc(long long a,long long b,long long p) { long long ans=0; while(b) { if(b&1)ans=(ans+a)%p; a=(a*2)%p; b>>=1; } return ans%p; } int main() { long long a,b,p; cin>>a>>b>>p; cout<<qc(a,b,p); return 0; }
|
最短Hamilton路径
定义f[i]
[j]:i为一个20位的整数,第k位表示是否经过了这个点,j表示最终停在那一点,初始状态,f[1]
[0]=1
答案就是f[1<<n-1] [n-1]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<bits/stdc++.h> using namespace std;
const int N=20,M=1<<N; int f[M][N],w[N][N];
int main() { int n; cin>>n; for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>w[i][j]; memset(f,0x3f,sizeof(f)); f[1][0]=0; for(int i=0;i<1<<n;i++) for(int j=0;j<n;j++) { if(i>>j&1) { for(int k=0;k<n;k++) { if(i>>k&1) f[i][j]=min(f[i][j],f[i-(1<<j)][k]+w[k][j]); } } } cout<<f[(1<<n)-1][n-1]<<endl; return 0; }
|
起床困难综合症
本题可以先求出全0和全1经过这些操作后究竟怎么了
如果0变成1显然不需要我们花费任何m啊
那直接加上
如果1-1
那么也要选,有肉谁不选呢,虽然要花钱,就是要减去我们m中的一部分来计入这一部分答案
也就是为什么(1<<j)<=m的原因
就是可以选的意思
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include<bits/stdc++.h> int n,m,ans,x,a1=0,a2=-1; char str[5]; int main(){ cin>>n>>m; while(n--){ cin>>str>>x; if(str[0]=='A') a1&=x, a2&=x; if(str[0]=='X') a1^=x, a2^=x; if(str[0]=='O') a1|=x, a2|=x; } for(int j=29;~j;--j){ if(a1>>j&1) ans+=1<<j; else if(a2>>j&1&&(1<<j)<=m) ans+=1<<j, m-=1<<j; } cout<<ans; return 0; }
|