訓練日記 多校

2021-08-21 13:44:00 字數 3669 閱讀 5882

題目大概:

給出乙個有n個位置的環,有m個位置有蘋果樹,你的倉庫在0的位置,你有乙個大小為k的籃子,問最少走多少步,可以把所有蘋果拿到位置0的倉庫。

思路:有3中拿的方式

1,從右邊走,拿夠蘋果,然後直接返回。

2,從左邊走,拿夠蘋果,然後返回。

3,繞一圈,把所有剩餘蘋果拿走。

顯然,第三種方式,是最後剩餘的蘋果很少<=k個時,這樣拿一圈,可以會走的步數少。但也有可能直接回去少,需要比較。

利用揹包,把這三種方式模擬一遍。

感想:如果改在直線上,倉庫位置不固定,會怎麼樣,那就沒有繞圈拿了,直接分析前兩種情況就i選哪個了,所有,很多題,有環後,就複雜了一些。

**:

#include using namespace std;

const int maxn=1e5+10;

pairg[maxn];

long long d[maxn];

long long dl[maxn],dr[maxn];

int cmp(paira,pairb)

else

}for(int i=cnt;i>=1;i--)

else

}long long ans=0;

for(int i=0;i<=cnt;i++)

for(int i=0;i+k+1<=cnt;i++)

if(k>=cnt)ans=min(ans,l);

printf("%i64d\n",ans);

}return 0;

}

tricks device

題目大概:

有乙個迷宮,有n個房間,m條道。1為入口,n為出口。從1道n有最短路。

問最少切斷幾條道,可以使人不能從1走到n為最短路。

問最多切斷幾條道,還可以從1走最短路走到n。

思路:求一遍1道n的最短路,並且維護1到n的最短路,最少變數為min,第二問答案就是m-min。

把圖中的所有最短路的邊重新建立最短路圖,然後跑一邊1到n的最大流。就是求的最小割。就是第一問的答案。

感想:這是乙個最短路和最大流結合的題目。

最大流,就考察了乙個最小割轉化為最大流來求,感覺難點還是求最短路的最少邊,需要改變最短路的**。

就是改動最短路的**,既然可以求最少,也可以求最多,當然,也可以在最短路過程中維護其他的。

**:

#include using namespace std;

#define rpef( i , a , b ) for ( int i = a ; i <= b ; ++ i )

#define rep( i , n ) for ( int i = 0 ; i < n ; ++ i )

#define copy( a , x ) memcpy ( a , x , sizeof a )

typedef long long ll ;

const int maxn = 3010 ;

const int maxe = 100010;

const int maxq = 200010;

const int inf = 0x3f3f3f3f;

struct edge

} ;struct network

void addedge ( int u , int v , ll c , ll rc = 0 )

void rev_bfs () }}

ll isap ()

for ( i = cur[u] ; ~i ; i = edge[i].n )

if ( edge[i].c && d[u] == d[edge[i].v] + 1 )

break ;

if ( ~i )

else

}return flow ;

}} ;network net ;

int n,m;

struct node1edge[maxe];

int id;

int head[maxn];

void init1()

void addedge(int u,int v,int w)

bool vis[maxn];

int side[maxn];

int dist[maxn];

void spfa(int s)

}if (dist[v]==dist[u]+edge[i].w)}}

}}void getmap()

}}int main()

spfa(1);

net.init();

getmap();

net.s=1;net.t=n;net.nv=net.t+1;

printf("%i64d %d\n",net.isap(),m-side[n]);

}return 0;

}

annoying problem

題目大概:

給出一棵樹,n個點,(n-1)條邊,然後給出q個操作,有乙個集合s。每次操作後,給出s集合中所有點相連的最短路長度。

1  x   為s集合增加x節點,

2  x  把s集合中的x節點刪除。

思路:用dfs序和lca就可以解決這道題。

dis陣列是給點到根的長度,lca(x,y)求x和ylca。

用了乙個公式,dis【u】-dis【lca(x,u)】-dis【lca(y,u)】+dis【lca(x,y)】;

有點容斥的味道。

感想:dfs序有很多樹上的應用,算是一種簡單樹鏈剖分題的有效解決方法。

**:

#include using namespace std;

const int maxn=1e5+50;

int cnt;

int head[maxn<<1];

struct poin

edge[maxn<<1];

sets;

int dis[maxn],dxu[maxn],be[maxn],d[maxn];

int vis[maxn];

int fa[maxn][25];

void add(int u,int v,int w)

int ans;

void init()

void dfs(int u,int fat)

for(int i=head[u]; i!=-1; i=edge[i].next)

}int lca(int x,int y)

for(int i=19; i>=0; i--)

}return fa[x][0];

}int solve(int u)

else

u = be[u] ;

/*cout<<"****"

return dis[u]-dis[lca(x,u)]-dis[lca(y,u)]+dis[lca(x,y)] ;

}int fl=0;

int main()

int sum=0;

printf("case #%d:\n",++fl);

d[1]=1;

dfs(1,-1);

int flag,x;

while(q--)

}else

}printf("%d\n",sum);}}

return 0;

}

訓練日記 20161024

初賽好像不會掛了,好開心!版權原因,不上傳題目。題意 求1 n n 1000 的排列中逆序對恰好為 k 個的排列數目。多測。題解 f i j 表示前 i 個數,逆序對個數恰好為 j的排列個數,易得轉移方程f i j i 1k 0f i 1 j k 用字首和優化可使複雜度降為o n2 題意 對於乙個長...

訓練日記 20170324

長久不更新部落格了。期間經歷了恰好被ag線踩的wc,經歷了漫長痛苦的小高考準備。現在終於可以重整旗鼓,向省選進發!幾個月來,唯一不變的是我仍然是個超級蒟蒻 版權原因,不上傳題目。題意 最小樹形圖 去年就接觸 聽說 過的演算法,一直沒有真正寫過。因為各種奇怪的細節錯誤,調了好幾個小時 比如找環時沒有判...

訓練日記 20170328

今天的題目似乎很水 好多人都提前ak離場了,於是提前一小時收題。但是我還是各種不會。思維江化?話說,聽到一句很有趣的話 山不在高,有林則徐 水不在深,有江 題意 給定一棵有n n 105 個節點的有根樹,編號互不重複。詢問有多少棵子樹內節點編號構成乙個連續區間。題解 水題,對於每個節點 i 記錄以該...