生活随笔
收集整理的這篇文章主要介紹了
牛客练习赛 65 (待补E-网络流)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
A.最值序列
排序后,前一半加后一半乘即可。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std
;
typedef long long ll
;
const int N
=500010;
const ll mod
=998244353;
ll a
[N
];
int n
;
int main()
{IO
;int T
=1;while(T
--){cin
>>n
;for(int i
=1;i
<=n
;i
++) cin
>>a
[i
];sort(a
+1,a
+1+n
);ll res
=0;for(int i
=1;i
<=n
;i
++){if(i
<=n
/2) res
=(res
+a
[i
])%mod
;elseres
=res
*a
[i
]%mod
;}cout
<<res
<<'\n';}return 0;
}
B.多重序列
注意ai,j=kbj,(b≥0)a_{i,j}=k^{b_j},(b\ge 0)ai,j?=kbj?,(b≥0)
那么容易發現∏j=1mai,j=k∑j=1mbj\prod_{j=1}^m{a_{i,j}}=k^{\sum_{j=1}^m b_j}j=1∏m?ai,j?=k∑j=1m?bj?
由此我們只需要統計每組的∑j=1mbj\sum_{j=1}^m b_j∑j=1m?bj?的大小,取個最大的然后快速冪求一下結果即可。
注意精度問題:亂搞精度瞎胡近位即可
當然也可以手寫求logloglog
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std
;
typedef long long ll
;
const int N
=2010;
int n
,m
,k
;
ll mod
;
ll
qmi(ll a
,ll b
,ll p
)
{ll res
=1;a
%=p
;while(b
) {if(b
&1) res
=res
*a
%p
;b
>>=1;a
=a
*a
%p
;}return res
;
}
int main()
{IO
;int T
=1;while(T
--){cin
>>n
>>m
>>k
>>mod
;if(k
==1) cout
<<1%mod
<<'\n';else{ll cnt
=0;for(int i
=1;i
<=n
;i
++){ll now
=0;for(int i
=1;i
<=m
;i
++){ll a
;cin
>>a
;now
+=ll(log(double(a
))/log(double(k
))+0.5);}cnt
=max(cnt
,now
);}cout
<<qmi(k
,cnt
,mod
)<<'\n';}}return 0;
}
C.二維動點
不難發現最終答案一定是{?1,0,1,2,3}\{-1,0,1,2,3\}{?1,0,1,2,3}這幾個值中的一個。
對于答案是{?1,0,1}\{-1,0,1\}{?1,0,1}很容易判斷,這里只簡要說明答案是333的情況。
首先n=2n=2n=2,并且四個點(原點、給的兩個點、所求點)構成一個平行四邊形答案就是333否則答案就是222。
如果輸入或者所求點是(0,0)(0,0)(0,0)直接跳過即可。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<map>
#include<cmath>
#include<iostream>
#include<algorithm>
#define x first
#define y second
using namespace std
;
typedef long long ll
;
typedef pair
<int,int> pii
;
const int N
=100010;
const ll mod
=998244353;
int n
,q
;
map
<pii
,int> mp
;
pii a
[N
];
int gcd(int a
,int b
)
{return b
?gcd(b
,a
%b
):a
;
}
bool check(pii a
,pii b
,pii c
,pii d
)
{return 1ll*(a
.x
-b
.x
)*(c
.y
-d
.y
)==1ll*(c
.x
-d
.x
)*(a
.y
-b
.y
);
}
int main()
{IO
;int T
=1;while(T
--){cin
>>n
>>q
;int cnt
=0;for(int i
=1;i
<=n
;i
++){cin
>>a
[i
].x
>>a
[i
].y
;if(a
[i
].x
==0&&a
[i
].y
==0){n
--,i
--;continue;}int d
=gcd(a
[i
].x
,a
[i
].y
);mp
[{a
[i
].x
/d
,a
[i
].y
/d
}]++;}while(q
--){int x
,y
;cin
>>x
>>y
;if(x
==0&&y
==0) {cout
<<0<<'\n';continue;}int d
=gcd(x
,y
);if(mp
.count({x
/d
,y
/d
})) cout
<<1<<'\n';else if(mp
.size()<=1) cout
<<-1<<'\n';else if(n
==2){pii p1
={0,0},p2
=a
[1],p3
=a
[2],p4
={x
,y
};bool ok
=0;if(check(p1
,p2
,p3
,p4
)){if(check(p2
,p3
,p1
,p4
)||check(p1
,p3
,p2
,p4
)) ok
=1;}if(check(p1
,p3
,p2
,p4
)){if(check(p1
,p2
,p3
,p4
)||check(p2
,p3
,p1
,p4
)) ok
=1;}if(ok
) cout
<<3<<'\n';else cout
<<2<<'\n';}else cout
<<2<<'\n';}}return 0;
}
D.最小公倍數
參考大佬題解
總結下這個題的幾個性質
①拆出來的數不一樣一定相對較優:相同的數說明這個數沒用
②拆出來的數一定是質數或者一個質數的次冪:我們知道一個數可以分解質因數假設拆出來的數不滿足前者條件,我們不妨假設一個數b=p1a1×p2a2b=p_1^{a_1}×p_2^{a_2}b=p1a1??×p2a2??,分析可知該數對答案的貢獻和這兩個數的效果相同p1a1,p2a2p_1^{a_1},p_2^{a_2}p1a1??,p2a2??,并且先然由于p1a1×p2a2<p1a1+p2a2p_1^{a_1}×p_2^{a_2}<p_1^{a_1}+p_2^{a_2}p1a1??×p2a2??<p1a1??+p2a2??,后者選擇方案更優。
③不同質數的地位相同,我們優先選擇小的質數。
④考慮一個質數我們選擇{pa1,pa2,…,pai}\{p^{a_1},p^{a_2},\dots,p^{a_i}\}{pa1?,pa2?,…,pai?},如果設a1<a2<?<aia_1<a_2<\dots<a_ia1?<a2?<?<ai?一定有a1=1,a2=2,ai=ia_1=1,a_2=2,a_i=ia1?=1,a2?=2,ai?=i,即連續選擇,如果aj=k>ja_j=k>jaj?=k>j那么讓aj=ja_j=jaj?=j結果一定更優。
根據上面幾個性質,先線性篩素數,然后跑分組背包即可。
每個質數是一個物品,如果選擇pi1,pi2,…,pikp_i^1,p_i^2,\dots,p_i^kpi1?,pi2?,…,pik?,那么體積vvv是pi1+pi2+?+pikp_i^1 +p_i^2 +\dots+p_i^kpi1?+pi2?+?+pik?,對答案的貢獻是f[j?v]×(k+1)f[j-v]×(k+1)f[j?v]×(k+1)
由于本題數據需要取模,而取模后大小會發生改變,這題最秒的是用logloglog代替乘積。那么價值www變為log(k+1)log(k+1)log(k+1)。
f[j]f[j]f[j]是一個pairpairpair,第一個值記錄logloglog,第二個值記錄原答案(取模),由于pairpairpair比較按照一個數,直接比較即可
注意:以下代碼dp體積從大到小枚舉優化了空間。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<cmath>
#include<iostream>
#include<algorithm>
#define x first
#define y second
using namespace std
;
typedef long long ll
;
typedef pair
<double,ll
> pdl
;
const int N
=100010;
const ll mod
=1e9+7;;
int prime
[N
],cnt
;
bool st
[N
];
pdl f
[N
];
int n
;
void init(int n
)
{for(int i
=2;i
<=n
;i
++){if(!st
[i
]) prime
[++cnt
]=i
;for(int j
=1;prime
[j
]<=n
/i
;j
++){st
[prime
[j
]*i
]=1;if(i
%prime
[j
]==0) break;}}
}
int main()
{IO
;int T
=1;init(100000);while(T
--){cin
>>n
;f
[0]={0,1};ll now
=0;for(int i
=1;i
<=cnt
;i
++){for(int j
=n
;j
;j
--){ll p
=prime
[i
];ll s
=prime
[i
];for(int k
=1;s
<=j
;k
++,p
*=prime
[i
],s
+=p
)f
[j
]=max(f
[j
],{f
[j
-s
].x
+log2(k
+1),f
[j
-s
].y
*(k
+1)%mod
});}now
+=prime
[i
];if(now
>n
) break;}pdl res
={0,0};for(int i
=0;i
<=n
;i
++) res
=max(res
,f
[i
]);cout
<<res
.y
<<'\n';}return 0;
}
此題讓我想到反素數這題。我是數論渣渣啊
E.游走配對
未學習待補~
要加油哦~
總結
以上是生活随笔為你收集整理的牛客练习赛 65 (待补E-网络流)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。