1.欧拉函数
int euler(int n)
{
int m=int(sqrt(n+0.5));
int ans=n;
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n>1)
ans=ans/n*(n-1);
return ans;
}
2.容斥原理
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+100;
const int mod=1e9+7;
typedef pair<int,int> PII;
#define x first
#define y second
#define pb push_back
#define INF 0x3f3f3f3f
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
vector<int> ans;
ll n,n1,an,len;
int vis[N];
void dfs(int u)
{
if(u==len)
{
int cnt=0;
ll x=1;
for(int i=0;i<len;i++)
{
if(vis[i])
x*=ans[i];
cnt+=vis[i];
}
if(x==1) return;
if(cnt&1)
an+=n1/x;
else
an-=n1/x;
return;
}
for(int i=0;i<=1;i++)
{
vis[u]=i;
dfs(u+1);
vis[u]=0;
}
}
int main()
{
cin>>n;
n1=n;
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
{
ans.pb(i);
while(n%i==0)
n/=i;
}
}
if(n>1)
ans.pb(n);
len=ans.size();
dfs(0);
cout<<n1-an<<endl;
return 0;
}
状压+DFS(判断是否合法)
DFS暴力直接T
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+100;
const int mod=1e9+7;
typedef pair<int,int> PII;
#define x first
#define y second
#define INF 0x3f3f3f3f
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
int x[]={1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,5}; //输入简化
int y[]={1,2,4,5,2,3,4,2,3,4,2,3,4,1,2,4,5};
int dist[20][20],st[20][20],g[20][20];
vector<PII> Q;
int sum,cnt,ans;// cnt记录每种状态里有多少格子被占领,sum为dfs实际被占领的格子,ans为掷筛子的次数
void dfs(int x,int y)
{
st[x][y]=1; //写到外面,
for(int i=0;i<4;i++)
{
int xx=x+dx[i],yy=y+dy[i];
if(xx<1||xx>5||yy<1||yy>5) continue;
if(dist[xx][yy]&&!st[xx][yy])
{
//st[x][y]=1;
sum++;
dfs(xx,yy);
}
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
memset(g,0,sizeof g); //记得初始化
for(int i=0;i<17;i++)
{
cin>>g[x[i]][y[i]];
Q.push_back({x[i],y[i]});
}
int n,res=0;
cin>>n;
for(int i=0;i<(1<<17);i++)
{
memset(dist,0,sizeof dist);//记得初始化
memset(st,0,sizeof st);//记得初始化
ans=cnt=sum=0; //每次状态也要初始化为0
for(int j=0;j<17;j++)
{
if(i>>j&1)
{
cnt++;
dist[Q[j].x][Q[j].y]=1;
ans+=(g[Q[j].x][Q[j].y]+5)/6; //比如 13 则正确返回 3
//不如分类讨论是g能否整除6
}
}
if(!dist[5][1]||ans>n) continue;
sum=1; //dist[5][1]=1
dfs(5,1);
if(sum==cnt)
res=max(res,cnt);
}
cout<<res<<endl;
}
return 0;
}