日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

奇技淫巧

發布時間:2023/12/15 综合教程 48 生活家
生活随笔 收集整理的這篇文章主要介紹了 奇技淫巧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0.如果不是秒切的話,解決問題的一般思路:

1.退而求其次:如果數據小、沒有某個限制怎么辦?(可以通過暴力分得到提示)

2.找到矛盾問題的根源,就是算法升級的關鍵,如果有了這個限制,怎么處理?

3.集中處理這個矛盾

本篇博文記錄一些機智操作,簡潔方法,奇技淫巧。

1.快讀:

void read(int &x)
{
    char ch;bool flag=false;
    while(!isdigit(ch=getchar()))
        (ch=='-')&&(flag=true); 
    for(x=num;isdigit(ch=getchar());x=x*10+num);
     (flag)&&(x=-x);
}

注意:&x和&&前后兩個的順序

支持:整形讀入。包括負數

2.取模優化:

inline int mod(int x)
{
    return x-p*(x/p);
}

3.線段樹define操作

struct node{
    int l,r;
    int add,ch;
    int mx,hx;
    int had,hch;//一段時間內最值  
    #define ad(x) t[x].add
    #define ch(x) t[x].ch
    #define mx(x) t[x].mx
    #define hx(x) t[x].hx
    #define ha(x) t[x].had
    #define hc(x) t[x].hch
    #define l(x) t[x].l
    #define r(x) t[x].r
}t[4*N];

摘自:cpu監控

4.define int long long

適用于無腦調試

但是空間極其緊張,除非沒時間改,否則不要用這個。

5.num[++num[0]]=x;

用num[0]計數,有多個數組的時候,不會弄混cnt名稱

6.fix

當數組中可能遇見負數的時候,可以考慮采用修正值fix,將取值的區域平移。

如:NOIP2016 D1T2 天天愛跑步, 處理d[si]-2*d[lca]<0 , w[x]-d[x]<0時,取值范圍在:[-n,n]

直接再加上n,平移到[0,n]就可以直接處理了。

7.區間中位數

二分一個中位數的值ans,大于ans的賦為1,小于-1(等于再說)

找區間內有無連續子段和大于0,判斷ans+還是ans-

8.字符讀入避免空格

ztb法:char s[] scanf("%s",s+1) 利用字符串自動剔除前面空格,并且讀到下一個空格位置。

chen_zhe法:char c scanf("%s",&c) 敢情這也可以。。。。

9.Hungary匈牙利算法每次memset的小優化(默認左部點出發dfs)

①一般情況下,我們是每次找到一個右部點,vis[y]=1,之后每次memset一下vis

②但是,有的時候,右部點很多,memset一下,nleft*nright 就掛了。

而如果左部點很少,可以嘗試標記左部點的vis,

因為,我們之所以標記vis,是因為,不能在dfs(pre[y])時,從pre[y]里不斷返回pre[y]自己(考慮代碼模擬一下)。

如果標記左部點,那么,回到自己時,會因為已經vis,直接返回0

換句話說,①方案是不讓你找到y,而②方案,是回到自己再打斷。本質一樣。

③我們也可以用一個棧sta[],收集右部點vis的點,用彈棧并歸零處理vis。

為什么復雜度在②條件下沒問題??

其實,最壞和②復雜度是一樣的,一般情況下更優。

因為,我們每找到一個!vis[y],就要做出選擇,要么!pre[y] 返回true,要么dfs(pre[y])

返回就返回了,打斷搜索。如果dfs下去,那么必然要到了一個新的左部點。

所以,每vis一個,最多多訪問一個左部點。所以,sta[]中元素的數量和左部點數量是一致的。

所以,最壞情況下,和②是一樣的。

(2018.9.8 update:其實根本可以不用每次嘗試清空什么vis!!!

我們可以采用時間戳的東西,vis[i]變成int數組,表示最后一次訪問這個右部點的左部點的編號!

如果這一次的沒有訪問i,即vis[i]!=id 那么就令vis[i]=id,就不用每次清空了!

  

int vis[N],pre[N];
int id;
bool dfs(int x){
    for(int i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(vis[y]!=id){
            vis[y]=id;
            if(!pre[y]||dfs(pre[y])){
                pre[y]=x;
                return true;
            }
        }
    }
    return false;
} 
for(int i=1;i<=mx;i++){
    id++;
    if(dfs(i)) ans++;
}

10.多個點的lca

dfs序最小點和dfs序最大點取lca即可。

因為dfs總是先搜完一個子樹,又因為兩個點遍歷時間相差最遠。畫圖理解一下。

類似:JZ模擬賽 8.9B組T3

11.區間維護最小值,支持刪除,插入

1.multiset

2.差的最小值呢?兩個set,第二個set維護數值set相鄰兩個的差值。插入刪除用前驅后繼處理。

詳見:JZ模擬賽 8.9A組T3

12.雙哈希

有的時候,出題人要卡你。一個哈希值可能出現的差錯是:

本來不同的兩個串,通過取模運算,就可能相同了。

所以,我們通過兩個串,如果兩個有一個哈希值不同,就認為串不同了。

否則,認為串相同。

注意,不可能出現相同的串哈希值不同的情況,因為算法一樣,得到的哈希值一定相同。

13.曼哈頓距離轉切比雪夫距離

(x,y) -> (x-y,x+y)重新設置點的坐標。

(x1,y1),(x2,y2) -> (x1+y1,x1-y1), (x2+y2,x2-y2)

分類討論可以證明:|x1-x2|+|y1-y2|=max(|x1-x2|,|y1-y2|)

這樣,就可以把一個加法變成最值問題。

可以處理曼哈頓距離最小生成樹。

用兩個set一個維護沒有加入當前點集中的點,橫坐標,縱坐標。

用四個數維護當前點集最小x,最大x,最小y,最大y

每次從set找四個點和最小x,最大x,最小y,最大y找最小距離加進去。

因為,只要從x找一個max,y找一個max,再取max就可以。

14.變進制數存儲狀態,狀壓dp

變進制法不錯的講解:NKOJ1633 神仙開山【變進制數狀壓DP】

還有一個應用:JZ模擬賽 8.18 A組T3

就是,根據每個數的出現次數不同,每個數位置的進制都不同。

這樣,可以達到壓縮狀態數到最小的結果。

15.一點反演技巧

(i,j)=1 時,等價于:∑d d|i&&d|j u(d) =1

(i,j)!=1時,等價于:∑d d|i&&d|j u(d) =0

即通過判斷i,j所有公約數的u的和是否為1,判斷i,j是否互質。

證明:

i,j互質的時候,公約數只有1,u(1)=1

i,j不互質的時候,公約數就是i,j最大公約數的約數。

設gcd(i,j)=p1^q1*p2^q2*...pk^qk

那么,如果取兩個以上的pi,u就是0,不影響答案。

所以,就是取p1、。。。pk一個或不取的方案數要考慮

取零個:C(k,0)個1

取一個 :C(k,1)個-1

取兩個 :C(k,2)個1

。。。

所以,最后的答案是:C(k,0)-C(k,1)+C(k,2)-C(k,3)+...+C(k,k)

根據組合數的性質,不論k是奇數還是偶數,答案都是0

證畢。

16數學期望dp小結

總結:

數學期望以難以證明的性質,花樣繁出的特點聞名于OI界。

其難以下手的恐懼,令不少蒟蒻心有余而力不足。

還是抓住關鍵的線性遞推式,和期望定義 。 慢慢仔細分析。

對于期望狀態的設計:

1.多個終點一個起點,就f[i]表示,從i到終點的期望步數,f[s]即為答案

2.多個起點一個終點,就f[i]表示,從起點到i的期望步數,f[t]即為答案

3.與終點無關的樹形期望dp,通常往子樹對i,父親對i影響考慮,和一般的樹形dp類似。

17.曼哈頓距離和切比雪夫距離轉化

18.gets()讀入整行字符串,然后再 處理。

或者getchar()讀入空格換行,scanf("%s")讀入單詞等

19.擴展歐拉定理:

$b^cspace mod p=b^{cspace mod p+phi(p)}mod p (c>phi(p))$

p,b可以不互質

20.計算三角形面積。

坐標:(x1,y1),(x2,y2),(x3,y3)

把(x3,y3)移動到原點。得到新的(x1,y1),(x2,y2)

S=|x1y2-x2y1|/2

可以避免精度誤差

21.二分圖帶權最大匹配

如果左部點只連接兩個邊,可以認為是兩個右部點之間連接了一條邊。

形成了一個無向圖(可能不連通),相當于給邊定向。

22.無理數的高精度處理

(適用于($(a+b imessqrt{x})^k$):

1.保留“a+b*根號”的形式:構造有序數對:(a,b),即可定義乘法。

2.精度問題:令

無理項消除,N是整數。如果$(a-b imessqrt{x})^k)$小于1的話,k比較大,就逼近0,k比較小,double可以承受。

例題:圓——高精無理數的處理

23.快速質因數分解:

如果要多次詢問在1e7范圍內的質因數分解,可以利用線性篩預處理每個數的最小質因子,然后不斷除以mindiv,即可在低于logn時間下完成分解。

而且質因子已經自動排好序了。

例題:CF757E Bash Plays with Functions

24.十進制快速冪(專治高精快速冪)

和二進制快速冪原理一樣。

y要循環$log_{10} y$次。

每次x要左移一位,相當于一個快速冪$log_2 {10} $次。

所以,總的復雜度其實也是:$log_{10} y imes log_2 {10} = log_{2} y$

但是,當y是一個高精度的時候,如果用十進制儲存,每次/2是O(長度)的,會TLE。

然而十進制快速冪直接舍棄最后一位,可以O(1)進行移位。

(由于復雜度在低精度下是一樣的,所以除了高精快速冪,并沒有什么卵用)

25.爆棧的處理方法

26.HASH判斷循環節

對于O(1)判斷si是sj的循環節:

hash(sj)*p^leni+hash(si)=hash(si)*p^lenj+hash(sj)

證明方法類似kmp的循環節證明。

27.C(n,m)奇偶性

結論:C(n,m)為奇數,當且僅當n&m=m,即m是n的子集。

證明:

根據LUCAS定理,C(n,m)=1 mod 2 意味著,n,m二進制上的每一位,都有n是1,m是0,或者n是1,m是1.或者n是0,m是0.

如果n是0,m是1的話,那么C(0,1)=0,那么就是0了。

28.所有取值的前k最值問題

考慮每個可能的決策點是否有貢獻。

1.起初把每個點的最優解找出來,帶著點的id,放進堆里面。

2.從堆里取出最優解。

3.把和這個id有關的次優解找出來,放進堆里。

重復2、3

適用于一些有固定可能存在的決策點。并且能夠快速找到和這個點有關的第k優的值。

例題:BZOJ3689: 異或之

[NOI2010]超級鋼琴

29.轉化研究對象:

枚舉每個決策點,計算決策點包含的物品的貢獻——>枚舉物品,計算對能產生影響的決策點的貢獻。

后者,用于計數,就是分開考慮每個元素。對于最值決策,計算之后直接對決策點取最值。

30.-Wall -W

工具——編譯選項——編輯器——編輯時加入以下命令:-W -Wall

小錯可以警告

#pragma GCC ("-W1,--stack=128000000)手動開棧。

31.對于一些序列兩次取值的問題(兩次取值位置不相交)

可以正著dp,f[i],前i個位置選擇一個

再反著dp,g[i]i~n位置選擇一個。

然后枚舉分界點,即可。

ans=max(ans,f[i]+g[i])

32.雪球數:

一個數的所有非空前綴組成的數都是素數。

例如:313 :3,31,313都是素數。

然而,雪球數有最大的數并不是無限的:73939133

33.NOI Linux編譯

1.進入Linux虛擬機

2.桌面新建文件。打開。

3.復制代碼進去。

4.重命名為my.cpp(后綴為cpp)

5.Ctrl+Alt+T 進入終端

6.輸入cd Desktop進入桌面界面(忘了文件名,輸入ls Desktop 顯示桌面的所有文件)

7.輸入g++ my.cpp -o my.exe

(有需要的話,后面加上-std=c++11 -Wall -O2)

8.如果回車之后,沒有其他信息(沒有error),那么編譯成功。

9.接下來輸入./my.exe (注意之間沒有空格)表示進入這個exe

然后類似windows下的cmd,直接輸入數據即可。

(按動↑可以尋找上面進行過的命令)

34.半平面交atan2

排序時,求向量旋轉角的時候,用atan2(y,x)比較好

既可以保證精度,而且范圍是在(-Pi,Pi]的。可以表示所有的旋轉角。而且,如果atan2(t,0)的話(t>0),會返回Pi/2,

并不會因為tan(Pi/2)不存在而RE等。

35.int a=floor((double)b+0.5)

適用于:FFT等需要四舍五入以及處理-0.0的情況。
(注意,負數的時候,強轉int是向中取整,floor是向下取整,有所不同。看情況決定)

而且,FFT最后輸出的時候,

for(reg i=0;i<=m;++i){
        b[i].x/=n;
        int pp=b[i].x+0.5;
        printf("%d ",pp);
    }

代替

for(reg i=0;i<=m;++i){
        b[i].x/=n;
        printf("%.0lf ",fabs(b[i].x));
    }

可以快一倍!

還有一個東西叫round(x)

(int)y=round((double)x)

四舍五入函數。

36.FFT三次變兩次:

就是把P(x)=F(x)+G(x)i

P(x)^2虛數部分/2即可。節省一次DFT

傅里葉變換(FFT)學習筆記

37.O(1)求LCA

用歐拉遍歷序遍歷樹,然后RMQ記錄深度。LCA就是之間深度最淺的,O(1)查詢

詳見:LCA 最近公共祖先

38.堆優化dij的一個小剪枝

1.不必每次把所有的出邊更新到的都加入到堆里

類似spfa,如果dis[y]>dis[x]+e[i].val那么dis[y]=dis[x]+e[i].val,q.push(po(y,dis[y]))

這樣常數會小一些。多次dij,優化就明顯了。

2.還可以用num記錄已經確定的點的個數,如果num=0直接return

適當減少了常數(但是如果要多次dij的話,別忘了清空堆)

39.關于平均值的二分

上面有中位數的二分,平均值也可以二分

每個數減去平均值,如果區間和大于等于0,那么可以

fzyzojP1635 -- 平均值

40.一個前綴問題

一個有向圖,S到T經過至少k條邊的最短路,這個要T自己和自己連個自環,表示保留下來

2.11考試

41.關心應該關心的

縮減冗余狀態:各種DP中用到

合并類似轉移及狀態:數組平移,維護分段函數,20190211 模擬訓練 A. 大貓咪

修改之間忽視并不會變的:虛樹、動態DP

42.異或下線性方程組的自由元個數:

先變成n*(n+1)的矩陣

然后高斯消元,如果某一個id找不到,那么一定是自由元了,計數器++

注意,每次找i和消除必須在全局位置,并且用一個vis標記表示是否還能動(因為有時候存在自由元X_i,但是第i行其實還能用)

最后削成的上三角矩陣,除了無解情況,剩下的一定有唯一解

(一般的線性方程組也是這樣求,只不過xor下的自由元用的比較多)

代碼見:bzoj4671: 異或圖——斯特林反演

43.一個通用技巧是:

一個通用技巧是:

找到兩個數組f,g

f范圍寬松好統計,g范圍嚴格難統計但是和答案有直接關系,

這樣,只要得到f和g的關系,就可以找到答案!

經常是可以得到f由g的表達式,然后斯特林反演或者二項式反演得到g的求法

也可以用多項式科技

數論函數的反演也可以這么做。

luoguP4841城市規劃

bzoj4671: 異或圖——斯特林反演

已經沒有什么好害怕的了——二項式反演+經典套路

44.枚舉LCP

一些對于字典序大小,或者二進制下有大小比較限制的按位操作的題

枚舉LCP可以有效體現比較大小的“實質”

一般外層枚舉LCP,內層用DP處理方案。

來自多校的一個題——數位DP+卡位

45.O(n^2)插值

[學習筆記]拉格朗日插值

46.一種生成函數還原序列的方法

有時候,兩個生成函數卷積起來,要展開以后求x^k的系數,但是k很大。

①如果一個生成函數的次方的話,就是組合意義小球放盒子了,O(1)有公式,LUCAS求組合數

②否則考慮能不能把其中一個的生成函數變成有限項,使得項數在O(n)以內

例如:自古槍兵幸運E

47.給DAG轉移重新定向

可以做到O(sqrt(m))的出邊個數。支持暴力枚舉Day5

48.樹剖維護子樹&&連通塊信息

PK LCT

基于動態DP的思想,記錄往輕兒子的貢獻。重兒子現場計算。Day5

便于打標記。便于寫。(畢竟是靜態樹)

49.取Ln

1.有標號圖計數,F表示所有情況,G表示連通情況。則:G=Ln(F)

反之,F=exp(G)

證明可以參考:

luoguP4841城市規劃

COGS 2353 2355 2356 2358 有標號的DAG計數

2.把乘法變成加法,

①多項式降次

付公主的背包

luoguP4705玩游戲

②把答案大的變小,仍然滿足單調性,所以取最小值方案還是不變的。

[BJOI2019]奧術神杖取Ln直接就變成0/1分數規劃了

3.碰見Ln(f)很麻煩?

求導就把f搞出來了。

4.求積分時候,處理分式分母

待定系數法。1/(ax+b)->Ln(|ax+b|)直接加上絕對值,求導回去還是成立的

50.分母沒有逆元

前提是求一個分子分母都是連乘積的分式

可以考慮表示成:x*p^y的pair形式,最后上下把p的次數相減(類似擴展Lucas)

具體操作:(a,b)*(c,d)=(a*c,b+d)

然后檢查(a,b):如果a%mod==0,(a,b)->(a/mod,b+1),否則(a,b)->(a%mod,b)

顯然這樣取模,mod的次數不會減少。

51.DINIC從T開始BFS常數更小

顯然DINIC的瓶頸在于增廣。

所以一些必然不會到達T的點就不用訪問了。

所以從T開始搜分層圖。

雖然一些點S不能到達,但是浪費的只是BFS的常數,反之浪費的就是增廣時候的常數了。

52.

53.真·奇技淫巧

O(p)預處理,O(1)任意底數,任意質數的快速冪

$a^b=G^{log_G{a^b}}=G^{b imes log_Ga}$

然后$log_Ga$對于所有的$a in [0,p-1]$可以預處理

對于$G^{x}$可以直接預處理

54.樹上點集到點集的最大值

邊權為正數

一個常用的套路:一個樹上點集的直徑,可以直接合并兩個集合得到。四個端點C(4,2)計算即可。

貓的某個隨機連通塊直徑題、安師大的某個O(n^4)預處理二分+前綴和查詢、51nod1766

55.編號區間點集,信息可以合并?

一個常用套路:編號區間?線段樹!線段樹區間維護這個區間的信息即可

MaxMex51nod1766

56.不能立刻決定球的顏色?

每個球的顏色個數固定,不能放一個球就染色

可以先認為是白色,然后某一個時刻欽定k個白色成為某一個顏色。只要知道之前有多少個白色就可以了。

UOJ#449. 【集訓隊作業2018】喂鴿子

57.IDFT的trick

如果遇到矩陣乘法套多項式,最后就求一個多項式的系數的話,可以考慮用IDFT的trick降低常數

具體是:直接把轉移矩陣的x換成$w_N^i$,得到$Ans(w_N^i)$最后再插值。

一個乘法的常數,比卷積的常數小太多了。

UOJ#424. 【集訓隊作業2018】count

58.__builtin

59.樹上后綴排序

有的時候很有用。比EXSAM好寫好調。

60.Cnt(S,T)

表示起點在S,終點在T集合的邊的條數

不能預處理,O(n)也有點慢。

可以bitset!處理S集合的出邊包括哪些編號,T集合的入邊包括哪些編號,求&

61.bitset與字符串匹配?

[國家集訓隊]JZPSTR

字符集很小的時候,可以對每個字符集維護出現位置。

各種插入刪除可以手寫bitset進行。

xi=x%Mi+1Mi

2.

總結

以上是生活随笔為你收集整理的奇技淫巧的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。