题目来源:2016沈阳区域赛
C.Recursive sequence
矩阵快速幂,思路来自oldz
#include <bits/stdc++.h>
typedef unsigned long long ll;
const ll mod=2147493647;
using namespace std;
ll A[7][7]={{1,0,0,0,0,0,0},{1,1,0,0,0,0,0},{1,2,1,0,0,0,0},{1,3,3,1,0,0,0},{1,4,6,4,1,0,0},{0,0,0,0,0,0,1},{0,0,0,0,1,2,1}};
ll tmp[7][7],c[7][7],d[7][7],ans[7][7],B[7][7];
inline void mul(ll a[][7], ll b[][7], int n){for(int i=0;i<n;++i)for(int j=0;j<n;++j)tmp[i][j]=0,c[i][j]=a[i][j],d[i][j]=b[i][j];for(int i=0;i<n;++i)for(int k=0;k<n;++k)if(c[i][k])for(int j=0;j<n;++j)if(d[k][j]){tmp[i][j] = (tmp[i][j]+(c[i][k]*d[k][j])%mod)%mod;}for(int i=0;i<n;++i)for(int j=0;j<n;++j)a[i][j]=tmp[i][j];
}
void mx_pow(ll ans[][7], ll A[][7], ll b){while(b){if(b&1)mul(ans,A,7);mul(A,A,7);b>>=1;}
}
ll n,a,b;
int main()
{int T;scanf("%d",&T);while(T--){scanf("%lld%lld%lld",&n,&a,&b);for(int i=0;i<7;++i)for(int j=0;j<7;++j)if(i!=j)ans[i][j]=0;else ans[i][j]=1;for(int i=0;i<7;++i)for(int j=0;j<7;++j) B[i][j]=A[i][j];mx_pow(ans,B,n-2);a%=mod;b%=mod;ll res = (ans[6][0]%mod+(3*ans[6][1])%mod+(9*ans[6][2])%mod+(27*ans[6][3])%mod+(81*ans[6][4])%mod+(a*ans[6][5])%mod+(b*ans[6][6])%mod)%mod;printf("%lld\n",res);}return 0;
}
E.Counting Cliques
搜索,建图时有个比较重要的优化,写完代码会发现用到的边,只有由编号小到大的单向边。。。根本没想到搜。。。总结一下吧
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
typedef long long ll;
using namespace std;
int n,m,s,x,y,tmp[111],cc,ans,mp[111][111],vis[111];
vector<int> G[111];
inline int ck(int x){for(int i=1;i<=cc;++i) if(mp[tmp[i]][x]==0) return 0;return 1;
}
inline void dfs(int u){if(cc==s){++ans;return;}for(int i=0;i<G[u].size();++i){int v=G[u][i];if(!vis[v]&&v>u&&ck(v)){tmp[++cc]=v;vis[v]=1;dfs(v);--cc;vis[v]=0;}}
}
vector<int> tt;
inline void del(int x){for(int i=0;i<G[x].size();++i){int v=G[x][i];tt.clear();mp[x][v]=mp[v][x]=0;for(int j=0;j<G[v].size();++j){if(G[v][j]!=x)tt.push_back(G[v][j]);}G[v]=tt;}G[x].clear();
}
int T;
int main() {scanf("%d",&T);while(T--){ans=0;scanf("%d%d%d",&n,&m,&s);for(int i=1;i<=n;++i){G[i].clear();for(int j=1;j<=i;++j)mp[i][j]=mp[j][i]=0;}for(int i=1;i<=m;++i){scanf("%d%d",&x,&y);if(x>y)swap(x,y);G[x].push_back(y);//!!!!important!!!!mp[x][y]=mp[y][x]=1;}for(int i=1;i<=n;++i){cc=0;vis[i]=1;tmp[++cc]=i;dfs(i);vis[i]=0;del(i);}printf("%d\n",ans);}return 0;
}
G.Do not pour out
二分+微积分,膜一发wst