2016多校第10場

2021-07-17 00:22:16 字數 3527 閱讀 1630

1001 media

tag:二分

題意給你乙個排好的n個數, 讓你求l1, r1, 和 l2, r2這兩區間合併起來的中位數。 

分析:我們可以很容易將這個問題轉化為第k問題, 因此我們二分這個數, 假設他是第k大那麼小於等於它的數的數量肯定大於等於k。

#include #include #include using namespace std;

const int maxn = 100000 + 100;

int a[maxn], hash[maxn], d, b[maxn];

int n, m;

inline int get(int l, int r, int num)

int query(int l1, int r1, int l2, int r2, int k) else l = mid + 1;

}return res;

}int main()

sort(hash+1, hash+1+n);

d = unique(hash+1, hash+1+n) - hash - 1;

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

b[i] = lower_bound(hash+1, hash+1+n, a[i]) - hash;

while(m--) else

printf("%.1f\n", res);}}

return 0;

}

1005 road

題意: 有n個村莊, 村莊與村莊之間有n-1條道路相連線,現在告訴你第i天需要從村莊a到村莊b運送物資, 因此你需要保證第i天村莊a到村莊b的道路是可用的, 剛開始所有的道路都不可用,你可以選擇一條路讓他可用或者不可用,但是一條道路只能開或者關一次, 每一條道路每執行一天需要花費一些錢, 現在問你第i天的花費。

tag: 線段樹 + 轉換思維

分析:首先考慮每一路, 我們需要維護出這條路最早開始和最晚關閉的時間(可以用線段樹統計)。 然後我們在考慮每一天, 我們肯定可以處理處第i天需要開啟哪些道路和關閉那些道路, 這樣就可以用線段樹快速的算出答案。 感覺應該是用了兩個線段樹。

#include #include #include #include #include using namespace std;

typedef pairpii;

const int maxn = 200000 + 100;

const int inf = 0x3f3f3f3f;

struct segmentseg[maxn*3];

void build(int rt, int l, int r)

inline void push_down(int rt)

void update_mima(int rt, int l, int r, int x)

push_down(rt);

int mid = (seg[rt].l + seg[rt].r)/2;

if(r <= mid)

update_mima(2*rt, l, r, x);

else if(l > mid)

update_mima(2*rt+1, l, r, x);

else

}pii queryday(int rt, int i)

push_down(rt);

int mid = (seg[rt].l + seg[rt].r)/2;

if(i <= mid)

return queryday(2*rt, i);

else

return queryday(2*rt+1, i);

}void update_sum(int rt, int sg, int num)

int mid = (seg[rt].l + seg[rt].r) / 2;

if(sg <= mid)

update_sum(2*rt, sg, num);

else

update_sum(2*rt+1, sg, num);

seg[rt].sum = seg[2*rt].sum + seg[2*rt+1].sum;

}int n, m;

int w[maxn];

vectordayst[maxn], dayed[maxn];

int main()

dayed[m+1].clear();

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

for(int i=1; i<=m; i++)

node(int type, int x, int y1, int y2):type(type), x(x), y1(y1), y2(y2) {}

bool operator < (const node& r) const

}nd[2*maxn];

int nnd;

int c[2*maxn], nc;

inline int lowbit(int x)

int sum(int i)

return s;

}void add(int i, int val)

}int hash[2*maxn], nhash;

int main() else

}// couttag:dp 計數

題意:定義兩個字串的cjj_val = max對應位置相同的長度最大值, 現在計算cjj_val = m的長度為n的字串, 可以使用k個不同字元。

分析:我們定義dp[i][j]為已經構造了長度為i, 且後面有j個字元一樣的方案數, 那麼dp[i][j] = dp[i-1][j-1]*k(最後乙個一樣的字元有k種選擇),特別的dp[i][0] = sigma(dp[i-1][j])*(k*(k-1)) 0<=j<=m, (最後乙個字元不一樣有(k*(k-1)))中方案,那麼不超過cjj_val不超過m的方案數為sigma(dp[n][j]), 減去不超過m-1的方案數就是恰好為m的方案數, 由於m很小因此我們使用矩陣快速冪快速計算dp值。

#include #include #include #include using namespace std;

using namespace std;

typedef long long ll;

const ll m = 1000000007;

struct mat;

void debug(mat a)

}mat operator* (const mat a, const mat b)

return res;

}mat qk_mod(mat a, ll n)

return res;

}ll solve(ll n, ll m, ll k) {

// cout<<"k = "<>n>>m>>k;

// printf("n = %i64d, m = %i64d, k = %i64d\n", n, m, k);

ll res = solve(n, m, k) - solve(n, m-1, k);

res = (res%m + m)%m;

cout<

多校第9場

這道題挺水,只是要耐心的打表,我一開始只打了一半就不想做了,也是因為我的方法太麻煩了,把x,y座標分開存,處理的資料量差不多增加了一倍。這題有一點注意 題目中並沒有限制字串的長度,所以char陣列盡量開大些。下面是賽後ac的 include include include include inclu...

多校第4場1012

理解題意以後會發現時比較簡單的線段樹,理解題意以後首先應該想到乙個貪心,就是再尋找最終答案的第i個數時,餓哦們要盡量使這個數盡可能大。那麼我們找 1,pos i 1 這個區間中已經組隊的位置的最大值,記為l,然後找 l 1pos i 1 之間未被找過的最大的數。這裡組隊的意思是可以詳見程式,並不是被...

多校第4場1012

理解題意以後會發現時比較簡單的線段樹,理解題意以後首先應該想到乙個貪心,就是再尋找最終答案的第i個數時,餓哦們要盡量使這個數盡可能大。那麼我們找 1,pos i 1 這個區間中已經組隊的位置的最大值,記為l,然後找 l 1pos i 1 之間未被找過的最大的數。這裡組隊的意思是可以詳見程式,並不是被...