牛客网暑期ACM多校训练营(第一场)
牛客網暑期ACM多校訓練營(第一場)
A. Monotonic Matrix
考慮0和1的分界線,1和2的分界線,發現問題可以轉化為兩條不互相穿過的路徑的方案數(可重疊),題解的做法就是把一條路徑斜著平移,然后就轉化為不可重疊了。現在考慮,如何計算從(0,0)道(n,m)不相交不可重疊的方案數,一條從(0,1)出發到達(n-1,m),一條從(1,0)出發到達(n,m-1),將他們乘起來的結果還包含相交的情況,于是再減去從(0,1)到(n,m-1)與(1,0)到(n-1,m)的方案數。
#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define pb push_back #define MP make_pair #define fr first #define sc second typedef long long ll; const int N = 1e5 + 7; const ll mod = 1e9 + 7; using namespace std; ll n,m,CC[2005][2005]; ll C(int n,int m) {return CC[n][m];} int main() {rep(i,0,2003) CC[i][i]=CC[i][0]=1;rep(i,2,2003)rep(j,1,i) CC[i][j] = (CC[i-1][j]+CC[i-1][j-1])%mod;while(scanf("%lld%lld",&n,&m)!=EOF) {ll ans = ((C(n+m,m)*C(n+m,m))%mod - (C(n+m,m+1)*C(n+m,n+1))%mod+mod)%mod;printf("%lld\n",ans);}return 0; }B. Symmetric Matrix
關鍵在于把這個矩陣,考慮成一個鄰接矩陣,然后發現一個每個點有兩條邊,且無自環,可以有重邊。這張圖實際上就是,每個點都屬于唯一的一個環,環的大小大于等于2。求這種圖的方案數。好像第一類斯特靈數?還得遞推搞一下。詳見:大佬的推導
#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) #define pb push_back typedef long long ll; const int N = 1e5 + 7; using namespace std; ll dp[N],n,m; int main() {dp[1] = 0, dp[2] = 1, dp[3] = 1, dp[4] = 6;while(scanf("%lld%lld",&n,&m)!=EOF) {if(n<=4) {printf("%lld\n",dp[n]%m);}else {ll M;rep(i,5,n)M = 1LL*(i-1LL)*(i-2LL)/2LL,M%=m,dp[i] = (((((i-1)*dp[i-1])%m + ((i-1)*dp[i-2])%m)%m) - (M*dp[i-3])%m + m)%m;printf("%lld\n",dp[n]);}}return 0; }D. Two Graphs
\(n!\) 枚舉與 \(G1\) 同構的圖,在 \(G2\) 中找到相應的邊,如果 \(m1\) 條邊都可以匹配到,則將這種方案中用到的邊壓成一個64位二進制數,放到set里去重。另一種思路是,出現重算的情況就是,這個同構的圖與自身的圖相同,即使用這些點的映射,形成的新圖與原圖一致,這種自同構的情況要從答案中除去。
#include <bits/stdc++.h> typedef unsigned long long ll; const ll seed = 31; const ll mod = 1e9 + 7; inline int read() {char c = getchar();int x=0, f=1;while(c<'0'||c>'9'){if(c=='-')f = -1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; } using namespace std; int n,m1,m2,g[11][11],PH[11]; pair<int,int> p[1111]; int main() {while(scanf("%d%d%d",&n,&m1,&m2)!=EOF) {set<int> s;s.clear();memset(g,0,sizeof(g));for(int i=1;i<=m1;++i) {int u=read(),v=read();g[u][v] = g[v][u] = 1;}for(int i=1;i<=m2;++i) {int u=read(),v=read();p[i] = make_pair(u,v);}for(int i=1;i<=n;++i) PH[i]=i;do{ll hs=0,cnt=0;for(ll i=1;i<=m2;++i){if(g[PH[p[i].first]][PH[p[i].second]]) {hs |= ((ll)1<<(i-(ll)1));++cnt;}}if(cnt == m1)s.insert(hs);}while(next_permutation(PH+1,PH+1+n));printf("%d\n",(int)s.size());}return 0; }J. Different Integers
先寫了分塊莫隊tle,然后寫了曼哈頓mst莫隊tle,然后分塊亂狗tle,t到終場。結束后,加了個快讀,分塊莫隊ac..。還有其他一些做法,其實把整個序列在后邊復制一份,不就變成了單個區間詢問數字種類的模板題了。(讓快讀成為習慣。。。為何泥萌常數辣么小
#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define pb push_back #define MP make_pair #define fr first #define sc second typedef long long ll; const int N = 1e5 + 7; inline int read() {char c = getchar();int x=0, f=1;while(c<'0'||c>'9'){if(c=='-')f = -1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f; } using namespace std; int n,q,a[N]; struct pp{int l,r,id,ans;}Q[N]; int B,belong[N]; void build() {B = sqrt(n);for(int i=1; i<=n; i++) belong[i] = (i-1)/B + 1; } bool cmp(pp a, pp b) {if(belong[a.l] == belong[b.l]) return a.r < b.r;return belong[a.l] < belong[b.l]; } int sum=0,num[N]; void update(int p,int d) {if(num[a[p]]==1&&d==-1) --sum;else if(num[a[p]]==0&&d==1) ++sum;num[a[p]]+=d; } bool cmp1(pp a,pp b) {return a.id < b.id; } int main() {while(scanf("%d%d",&n,&q)!=EOF) {for(int i=1;i<=n;++i)num[i]=0;build();for(int i=1;i<=n;++i)a[i]=read();for(int i=1;i<=q;++i) {Q[i].l=read(),Q[i].r=read();Q[i].id=i;}sort(Q+1,Q+1+q,cmp);int l=0, r=n+1;sum = 0;for(int i=1;i<=q;++i) {while(r<Q[i].r)update(r,-1),++r;while(r>Q[i].r)--r,update(r,1);while(l<Q[i].l)++l,update(l,1);while(l>Q[i].l)update(l,-1),--l;Q[i].ans = sum;}sort(Q+1,Q+1+q,cmp1);for(int i=1;i<=q;++i)printf("%d\n",Q[i].ans);}return 0; }轉載于:https://www.cnblogs.com/RRRR-wys/p/9339002.html
總結
以上是生活随笔為你收集整理的牛客网暑期ACM多校训练营(第一场)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Canalys:预计2023年中国汽车出
- 下一篇: vivo Y100详细参数公布:5000