牛客國慶day3
給定一個序列,如果在 a i a_i ai之前有 a j < a i a_j<a_i aj<ai,那麼找到最小的 a j a_j aj,把所有這樣的 a j a_j aj相加。
4
2 1 4 3
例如樣例就是1前面的2,加上3前面的4。答案為6。
比賽的時候只想到了權值線段樹解法,離散化之後維護區間最小值:
struct node
{
int l, r, k, minn;
} tr[400040];
inline void update(int k)
{
tr[k].minn = min(tr[k * 2].minn, tr[k * 2 + 1].minn);
}
void build(int k, int l, int r)
{
tr[k].l = l;
tr[k].r = r;
if (l == r)
{
tr[k].minn = INF;
return;
}
int mid = l + r >> 1;
build(k * 2, l, mid);
build(k * 2 + 1, mid + 1, r);
update(k);
}
void insert(int k, int w)
{
if (tr[k].l == tr[k].r && tr[k].l == w)
{
tr[k].minn = w;
return;
}
int mid = tr[k].l + tr[k].r >> 1;
if (w <= mid)
insert(k * 2, w);
else
insert(k * 2 + 1, w);
update(k);
}
int query(int k, int l, int r)
{
if (tr[k].l == l && tr[k].r == r)
return tr[k].minn;
int mid = tr[k].l + tr[k].r >> 1;
if (r <= mid)
return query(k * 2, l, r);
else if (l > mid)
return query(k * 2 + 1, l, r);
else
return min(query(k * 2, l, mid), query(k * 2 + 1, mid + 1, r));
}
int b[100010];
int c[100010];
int a2[100010];
int b2[100010];
struct node2
{
int a, c;
bool operator<(node2 temp) const
{
return c < temp.c;
}
} p[100010];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &p[i].a), b[i] = p[i].a;
sort(b + 1, b + 1 + n);
int len = unique(b + 1, b + 1 + n) - b;
for (int i = 1; i <= n; i++)
c[i] = p[i].c = lower_bound(b + 1, b + 1 + n, p[i].a) - b;
sort(p + 1, p + 1 + n);
for (int i = 1; i <= n; i++)
{
a2[i] = p[i].a;
b2[i] = p[i].c;
}
build(1, 1, 100005);
long long ans = 0;
for (int i = 1; i <= n; i++)
{
insert(1, c[i]);
int temp = query(1, c[i] + 1, 100005);
if (temp == INF)
continue;
int pos = lower_bound(b2 + 1, b2 + 1 + n, temp) - b2;
ans += a2[pos];
}
printf("%lld\n", ans);
return 0;
}
碼量挺大的,看到他們的過題速度就知道事情不簡單,其實直接用set存前面所有數,二分查詢即可:
set<int> st;
int main()
{
int n;
long long ans = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
int temp;
scanf("%d", &temp);
if (st.upper_bound(temp) != st.end())
ans += *st.upper_bound(temp);
st.insert(temp);
}
printf("%lld\n", ans);
return 0;
}
有 n n n種花,每種花有 a i a_i ai種, m m m種不同的話可以組成一束花,問最多可以組成多少種花。
賽時用一個小頂堆一個大頂堆維護第k大,wa+tle七發之後瞎猜了一個結論改改過了。賽後發現別人都是二分,(明天一定補。
priority_queue<int, vector<int>, greater<int>> q1;
priority_queue<int> q2;
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
while (q1.size())
q1.pop();
while (q2.size())
q2.pop();
int n, m;
read(n);
read(m);
for (int i = 1; i <= n; i++)
{
int temp;
read(temp);
q1.push(temp);
}
if (m > n)
{
printf("0\n");
continue;
}
while (q1.size() > m)
{
int temp = q1.top();
q1.pop();
q2.push(temp);
}
long long ans = 0;
while (q1.top() > 1)
{
int k = q1.top() - 1;
ans += k;
while (q1.size())
{
int temp = q1.top();
q1.pop();
temp -= k;
q2.push(temp);
}
while (q1.size() < m)
{
int temp = q2.top();
q2.pop();
q1.push(temp);
}
}
while (q1.top())
{
int k = q1.top();
ans += k;
while (q1.size())
{
int temp = q1.top();
q1.pop();
temp -= k;
q2.push(temp);
}
while (q1.size() < m)
{
int temp = q2.top();
q2.pop();
q1.push(temp);
}
}
printf("%lld\n", ans);
}
return 0;
}
相關文章
- 【牛客訓練記錄】2024牛客國慶集訓派對day3
- 【牛客訓練記錄】2024牛客國慶集訓派對day2
- 【牛客訓練記錄】2024牛客國慶集訓派對day1
- 2020牛客國慶集訓派對4 C
- ABB (2020牛客國慶集訓派對day1)
- 2020牛客國慶集訓派對day4 F
- 2024國慶S綜合強化Day3
- 牛客
- OrzClick: 國慶寫個 ClickHouse 客戶端客戶端
- 【牛客訓練記錄】牛客周賽 Round 69
- 【牛客訓練記錄】牛客周賽 Round 70
- 【牛客】時間
- 牛客周賽48
- 【牛客_2020.10.20】漲薪
- 牛客錯題集
- 牛客練習賽
- 牛客小白月賽105
- 牛客周賽 Round 63
- 2024 牛客多校 6
- 2024 牛客多校 7
- 2024 牛客多校 8
- 牛客周賽 Round 57
- 牛客周賽 Round 56
- 2024 牛客多校 2
- 2024 牛客多校 1
- 2023 牛客多校 5
- 2024牛客多校6
- 2024牛客多校1
- 牛客小白月賽97
- 牛客小白月賽88
- 牛客周賽 Round 40
- 牛客小白月賽89
- 牛客周賽 Round 47
- 牛客周賽 Round 1
- 牛客周賽 Round 3
- 牛客周賽 Round 7
- 牛客小白月賽94
- 牛客周賽 Round 8