總體來說不算好做……但是確實也不難。
給定正整數n,k,求f(
n,k)
=∑ni
=1ik
f (n
,k)=
∑i=1
ni
k,結果對19260817取模。
1 <= n <= 1e7, 0 <= k <= 1e9
時限0.698s(???)
上來用拉格朗日插值法直接wa。。正解其實比想象的簡單。先尤拉篩出素數,對素數用快速冪求出i^k存起來。然後對合數的i^k只要用素數的結果求就可以了。
#include
using
namespace
std;
typedef
long
long ll;
const
int p = 19260817;
const
int maxn = 1e7+5;
bool flag[maxn];
ll f[maxn], prime[maxn], n, k, cnt;
inline ll pow_mod(ll a, ll b)
return res;
}inline
void sieve()
for (int j = 0; j < cnt && i * prime[j] <= n; ++j)
}}int main()
給出乙個長度為 n 的整數數列 a,對於這個數列進行任意多操作。每次選擇乙個任意的整數,並將任意 p 個數字加上這個數字。輸出 yes 或 no,表示能否通過這種方法將這個數列中每個數字同時變成零。
1 ≤ p ≤ n ≤ 1e5, |ai| <= 1e6
結論題。顯然當n==p時只有所有數字相等時才是yes;n>p時,數字總和如果是p的倍數則yes。其實憑感覺可以想到:要把所有數字變成0,和必須是p的倍數。不過嚴格的證明則是將所有n>p的情況轉化為n==p+1的情況。
#include
using
namespace
std;
int n, p, i, tmp, sum;
int main()
printf("%s\n", i == n ? "yes" : "no");
}else
printf("%s\n", sum % p ? "no" : "yes");
}return
0;}
給任意乙個大於 1 的正整數 n,輸出 n 可以分解成最少幾個質數(可以相同)的和。
2 ≤ n ≤ 1e15
據說是codeforces原題。
如果本身是質數那麼直接輸出1。
運用哥德**猜想,任何大於2的偶數可以被分解為兩個質數之和。也就是偶數輸出2。
如果n是奇合數但還可以被分解為兩個質數,那只可能是一奇一偶。偶質數只能是2,也就是說n-2必須是質數。
其他情況輸出3。
#include
using
namespace
std;
typedef
long
long ll;
ll n;
inline
bool isprime(ll m)
int main()
給出 n 個正整數,問有多少種方法在這 n 個數字的中取其中一些數字,使得這些數字之和超過 k。若答案超過 20 000 000,輸出 -1。
1 ≤ n ≤ 1e4
1 ≤ ai ≤ 1e8
1 ≤ k ≤ 1e10
降序排序,預處理字首和,然後dfs+剪枝。
最優性剪枝:如果當前和已經大於k則剪枝,ans要加上2^(剩餘數字個數)——這一步還可以剪枝:由於2^25>2e7,所以一旦剩餘數字個數大於等於25也剪枝。
可行性剪枝:如果當前和加上後面所有數(用字首和)都不大於k那麼剪枝。
#include
using
namespace
std;
typedef
long
long ll;
const
int maxn = 1e4+5;
int a[maxn], n, ans;
bool flag;
ll k, suma[maxn];
inline
void dfs(int dep, ll sum)
dfs(dep+1, sum + a[dep]);
dfs(dep+1, sum);
}int main()
給出整數數列 ,對整個數列進行盡可能少的次數操作,每次操作可以將數列中任意一項加 1 或者減 1,使得最終的數列 b1,b2,b3,…,bn 滿足對數列中的任一項 bi (i>=2),有 bi
=bi−
1+i bi=
bi−1
+i
。 求最少的操作次數。1 ≤ n ≤ 1e5,1 ≤ ai ≤ 1e10
設=,這題等價於求|c
1−x|
+|c2
−x|+
...+
|cn−
x|| c1
−x|+
|c2−
x|+.
..+|
cn−x
|的最小值。根據高中函式知識,x應該取cn的中位數。那麼我們構造出cn然後排下序取中間下標,這題就做完了……
#include
using
namespace
std;
typedef
long
long ll;
const
int maxn = 1e5+5;
ll a[maxn], b[maxn], ans;
int n;
inline ll fun(ll mid)
int main()
sort(a+1, a+1+n);
printf("%lld\n", fun(a[(n+1)>>1]));
return
0;}
對於給定的數字串a1
,a2,
a3,…
,an a1,
a2,a
3,…,
an
,每次可以進行如下操作: 選擇乙個數 i (1 < i < n),將 ai
a
i變成 ai
+1+a
i−1−
aia i+
1+ai
−1−a
i。問在經過任意多次的操作後,該數列的數字總和最小為多少?
1 ≤ n ≤ 1e5,0 ≤ ai ≤ 1e10令c
i=ai
+1−a
i ci=
ai+1
−a
i,這樣c數列有n-1項。注意到對ai
a
i的操作等價於交換ci
c
i與ci
+1c i+
1,那麼通過將c公升序排序後反構造出的a數列就是總和最小的數列啦。
#include
using
namespace
std;
typedef
long
long ll;
const
int maxn = 1e5+5;
ll a[maxn], c[maxn], sum;
int main()
printf("%lld\n", sum);
return
0;}
到今天為止,終於把以前寫的需要多一些深入思考的題目記錄完畢了。 新生訓練2
時間匆忙,先把自己 弄上明天考完再做詳細題解和補剩下的題 昨天組長在報告上說我題解認真,感到十分愧疚,來補題解,所以抓緊來補題解 a.b.c d eat candies 讀懂題很容易理解,先取最大的,然後如果最大的值大於另外兩個的和,則最大天數等於另外兩個的和,否則取另外兩個和與最大天數差值,除於2...
JXUST ECJTU新生訓練賽
a.此題由於字串的長度是10 5,所以利用o n 2 暴力來做的話,顯然是超時的,所以不採用這種方法,我們可以計算每個字元 出現的次數,而題目中 告訴pairs x,y and y,x should be considered different,所以組成的個數總和就是 每個字元出現的次數的乘積之和...
2021新生訓練題解02
a 思路 dp 由於每乙個點只能從該點的左側或上側到達,因此到達該點的最小花費一定在到達該點上側和左側之前產生,可得轉移方程 dp i j min dp i 1 j dp i j 1 注意特判i 1 0和 j 1 0 的情況 標程 b 思路 數學幾何 沿著柱面向上走,可將柱面展開,變成乙個矩形,兩點...