2019 杭電多校 第一場

2022-05-31 01:42:09 字數 3358 閱讀 3890

2019 multi-university training contest 1

給定包含 \(n\) 個數的序列,\(m\) 個詢問。詢問有兩種操作,操作 \(0\) 表示在陣列最後新增乙個新元素,操作 \(1\) 表示查詢區間 [l,r] 的子集的異或最大值。

線性基 貪心一條路上有 \(n + 1\) 輛車。第 \(i\) 輛車的長度為 \(l_i\),離終點的距離為 \(s_i\),最大車速為 \(v_i\),\(i\) 越大越靠近終點。每輛車不能超越前面的車,但車頭可以貼在前面車的車尾。每輛車經過了終點,仍繼續在路上跑。求第 \(0\) 輛車 (最後一輛車) 車頭通過終點線的最少需多少時間。

貪心 二分

二分時間。判斷 \(mid = (l + r) / 2\) 時間能否最後一輛車到達,若能到達則 \(r = mid\),否則 \(l = mid\)。

接下來是如何判斷時間 \(t\) 內最後一輛車能否到達終點。

從第一輛車 (最靠近終點) 開始列舉,維護乙個 \(cur\) 表示第 \(i\) 輛車車頭到終點的距離。第 \(i\) 輛車經過 \(t\) 時間後可以行駛 \(car[i].v * t\) 的距離,距離終點 \(car[i].s - car[i].v * t\)。但是如果前面有車,就要比較前車車尾離終點的距離 \(cur + car[i].l\) 誰更近。如果 \(car[i].s - car[i].v * t \le cur + car[i].l\),也就是第 \(i\) 輛車行駛 \(t\) 時間後距離終點更近,那麼由於不能超過前車,也就是只能貼在前車的車尾,\(cur\) 更新為前車車尾到終點的距離 \(cur + car[i + 1].l\)。如果 \(car[i].s - car[i].v * t > cur + car[i].l\),也就是不會超過前車,那麼 \(cur\) 就是當前車行駛 \(t\) 時間後車頭距離終點的距離。如果第 \(0\) 輛車行駛 \(t\) 時間後 \(cur \le 0\),說明可以到達。

#include using namespace std;

const int maxn = 2e5 + 10;

const double eps = 1e-8;

struct car car[maxn];

int n;

int check(double x)

return cur <= eps;

}int main()

for(int i = 0; i < n + 1; ++i)

for(int i = 0; i < n + 1; ++i)

double l = 0, r = 1e18;

int cnt = 0;

while (cnt < 100)

printf("%.6lf\n", r);

}return 0;

}

給定 \(n\) 個結點,\(m\) 條邊的有向圖,現在要刪除一些邊,使得結點 \(1\) 到 \(n\) 的最短路的長度增加,刪除邊的代價為邊的權值,求最少的代價。

最短路 最小割首先要找出所有的最短路,得到最短路圖。對最短路圖求最小割就是答案。

所有最短路的求法:先跑一遍單源最短路,可以用 \(dijkstra\) 演算法。\(dijkstra\) 演算法得到的是起點到所有點的最短距離,存放在 \(d\) 陣列中。那麼遍歷所有的邊,如果 \(d[i] + w_ = d[j]\) (\(w_\) 表示結點 \(i\) 到結點 \(j\) 的邊的權值),那麼該條邊一定在最短路圖上。

至於最小割用 \(dinic\) 演算法求解即可。

給出兩類點的座標,問能否用一條直線將兩類點分開。

題目看懂了就很好做了。

就是分別對兩類點求凸包,然後判斷兩個凸包是否相交。若不相交,則能夠用一條直線分開兩類點,否則不能。

其實就是判斷凸包是否相交的模板題。

#include using namespace std;

const double eps = 1e-8;

const double pi = acos(-1.0);

class point

point operator+(point a)

point operator-(point a)

bool operator

bool operator==(const point &a) const

double length()

};typedef point vector;

double cross(vector a, vector b)

double dot(vector a, vector b)

bool isclock(point p0, point p1, point p2)

double getdistance(point a, point b)

typedef vectorpolygon;

polygon andrew(polygon s)

u.push_back(s[i]);

}for(int i = s.size() - 3 ; i >= 0 ; --i)

l.push_back(s[i]);

}for(int i = 1 ; i < u.size() - 1 ; i++) l.push_back(u[i]);

return l;

}int dcmp(double x)

bool onsegment(point p, point a1, point a2)

// 判斷線段相交

bool intersection(point a1, point a2, point b1, point b2)

// 判斷點在凸包內

int ispointinpolygon(point p, vectors)

if (wn != 0) return 1;

return 0;

}void solve(polygon s1, polygon s2)

}for(int i = 0; i < c2; ++i)

}for (int i = 0; i < c1; i++) }}

printf("successful!\n");

}int main() else

}if(n == 1)

if(s1.size()) s1 = andrew(s1);

if(s2.size()) s2 = andrew(s2);

solve(s1, s2);

}return 0;

}

2019杭電多校第一場

dp i j k t dp i j k t dp i j k t 表示0 1 2,3 0,1,2,3 0,1,2,3出現的位置排序後為i,j k,t i,j,k,t i,j,k,t的方案數 列舉第t 1 t 1t 1位的情況進行轉移 對於限制情況,固定右端點,暴力列舉所有狀態,把所有非法狀態清零 i...

2019 杭電多校(第一場)

題目 1002 operation 線性基 題意給你n個數 兩個操作,查詢l r區間異或最大值 在陣列最後麵加一數 思路維護兩個陣列 1 b i j 儲存a 1 到a i 之間的第j位線性基。2 pos i j 儲存最大的l a l 使得b i j 有值。對於每一次詢問 l,r 如果pos r j ...

2019杭電多校第一場

從右到左分別為0 n輛車,每輛車有長度l,起始位置s和速度v,0座標在左邊,不能超車,單車道,問0號車到達0座標的最短時間。最短時間考慮二分時間,然後按這個時間從左邊第一輛車開始依次計算最終位置,最後判斷0號車的位置即可。include using namespace std const int n...