t1: 階乘
fact.cpp
【問題描述】
有 n個正整數 a[i],設它們乘積為 p,你可以給 p乘上乙個正整數 q,使 p*q剛好為正
整數m的階乘,求m的最小值。
【輸入】
共兩行。
第一行乙個正整數n。
第二行n個正整數a[i]。
【輸出】
共一行乙個正整數m。
【輸入樣例】16
【輸出樣例】
3樣例解釋:
當p=6,q=1時,p*q=3!
【資料範圍與約定】
對於10%的資料,n<=10
對於30%的資料,n<=1000
對於100%的資料,n<=100000,a[i]<=100000
分析:二分m
二分的上界要稍微大點,1e8,不然會漏掉答案。
驗證時對p分解質因子,然後求出m!裡面有多少個p的各個質因子,如果都比p多,那麼m就合法。
**:
#include
#include
#include
#define ll long long
#define n 600007
using
namespace std;
ll n, zs[n]
, t, a[n]
;
ll tot =
1, ans;
bool b[n]
;void
pre_work()
else
}}
ll max
(ll a, ll b)
void
cl(ll x)
a[zs[i]]++
, t =
max(t, zs[i]);
}}bool
check
(ll ain)
return1;
}void
find()
printf
("%lld"
, l);}
intmain()
cl(x);}
find()
;return0;
}
t2:上公升序列
(lis)
【問題描述】
給出乙個長度為 m 的上公升序列 a(1 ≤ a[i]≤ n), 請你求出有多少種 1…n 的排列, 滿足
a 是它的乙個 lis.
【輸入】
第一行兩個整數 n,m.
接下來一行 m 個整數, 表示 a.
【輸出】
一行乙個整數表示答案.
【輸入樣例1】
5 31 3 4
【輸出樣例1】
11【輸入樣例2】
4 23 4
【輸出樣例2】
5【資料範圍與約定】
對於前 30% 的資料, n ≤ 9;
對於前 60% 的資料, n ≤ 12;
對於 100% 的資料, 1 ≤ m ≤ n ≤ 15.
狀壓dp好題。
首先需要回憶o(nlogn)o(nlogn) 的方法,我們會維護乙個單調遞增的d陣列。
可以設計狀態f(s1,s2)表示選取的數的集合是s1,然後d陣列中元素的出現情況是s2。
這樣轉移是很簡單的。
但時空都無法承受。
於是我們考慮優化,不難發現s1是s2的子集。
因此我們三進製狀壓dp就行了。
**
#include
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define n 16
#define m 14348910
#define ll long long
using
namespace std;
int n,m,cf[n]
,a[n]
,wz[n]
,cf2[n]
;
ll f[m]
,ans;
void
dfs(
int k,
int lim,
int v)
v+=cf[k-1]
;dfs
(k+1
,lim,v)
;
v+=cf[k-1]
;dfs
(k+1
,lim-
1,v);}
intmain()
}if(c1)
if(f[vi])fo
(j,1
,n)
f[v]
+=f[vi];}
}if(i1==0)
break;}
}}dfs(
1,m,0)
;printf
("%lld\n"
,ans)
;return0;
}
t3 :相遇
(meet)
【問題描述】
豪哥生活在乙個 n 個點的樹形城市裡面,每一天都要走來走去。雖然走的是比較的
多,但是豪哥在這個城市裡面的朋友並不是很多。
當某一天,猴哥給他展現了一下大佬風範之後,豪哥決定要獲得一些交往機會來提公升交
往能力。豪哥現在已經物色上了一條友,打算和它(豪哥並不讓吃瓜群眾知道性別)交
往。豪哥現在 spy 了一下這個人的所有行程起點和終點,豪哥打算從終點開始走到起點與
其相遇。但是豪哥是想找話題的,他想知道以前有多少次行程和此次行程是有交集的,這
樣豪哥就可以搭上話了。這個路徑與之前路徑的有交集數量作為豪哥此次的交往機會。
但是豪哥急著要做交往準備,所以算什麼交往機會的小事情就交給你了。
【輸入】
第一行乙個正整數 n表示節點個數。接下來 n-1行,每行兩個正整數分別是 u,v表示節點
u和 v之間有連邊。接下來一行乙個 正整數 m表示路徑個數。然後有 m行,每行兩個正整
數分別是u,v分別表示 u到v之間有一條路徑。
【輸出】
輸出共m行,每行乙個整數,第 i行表示豪哥在這條路徑上獲得的交往機會。
【輸入樣例】
51 2
1 33 4
3 54
4 54 2
1 31 2
【輸出樣例】01
22【資料範圍與約定】
對於20%的資料n,m≤2000
對於另外20%的資料n,m≤50000
對於另外10%的資料n,m≤200000保證樹形結構是一條鏈
對於另外50%的資料n,m≤200000
分析:兩條路徑相交的情況就是:
1、這條路徑的lca在另一條路徑上。
2、某條路徑穿過這條路徑的lca。
我們用兩個樹狀陣列來維護,用dfs序。
對於第一種情況,我們維護這個點到根節點的路徑上面有多少個lca,然後相減就能得到答案。
對於第二種情況,我們在兩個節點上面打乙個+1的標記,在lca上面打乙個-2的標記,這樣就將整條鏈都+1了。
**:
#include
#define lowbit(x) ((x)&-(x))
#define treesum(t,x) (sum(t,r[x])-sum(t,l[x]-1))
using
namespace std;
const
int n=
2e5+10;
int n,m,l[n]
,r[n]
,stm;
int tot,to[n*2]
,next[n*2]
,final[n]
;int f[n][19
],dep[n]
;int t1[n]
,t2[n]
,ans;
void
change
(int
*tr,
int x,
int v)
intsum
(int
*tr,
int x)
void
link
(int x,
int y)
void
dfs(
int x,
int fa)
intlca
(int x,
int y)
void
calcans
(int x,
int y,
int lca)
intmain()
dfs(1,
0); cin>>m;
for(
int i=
1; i<=m; i++
)return0;
}
校內模擬 深邃(貪心)(二分答案)
簡要題意 一棵樹,有 k kk 個關鍵點,請你把樹劃分為若干聯通塊,使得每個聯通塊包含至少乙個關鍵點,最小化最大的聯通塊的大小。首先容易注意到可以二分答案。然後考慮怎麼判斷,進行dfs,每個點盡量貪心往下劃分。h vu hv u hvu 表示 u uu 為根的子樹,u uu 這個聯通塊還能多容吶的點...
校內模擬 記憶(狀壓DP)
考場想到了正解,然後被卡快取記憶體,gg 乙個顯然的轉化就是設e ie i ei 表示朋友選擇第i ii個串的時候的期望操作次數。則答案就是所有e ie i ei 的平均值。首先考慮乙個o n l2l o nl2 l o nl2l 的暴力,對於每個串,列舉所有其他串看有多少個位置相同,則我們能夠知道...
2018 10 17 校內模擬 管道(狀壓DP)
簡直有毒,出題人還一本正經的說 我覺得沒有去年noi pd2t 2noipd2t2 noipd2 t2難啊 我只想說,去年d2t 2d2t2 d2t2 的轉移方程那裡有這麼鬼畜。首先利用兩個陣列f,d pf textdp f,dp 來進行狀態轉移。定義如下fi,staf fi,sta 表示不向點i ...