贪心 codeforces 878E
Posted foreverpiano
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心 codeforces 878E相关的知识,希望对你有一定的参考价值。
http://codeforces.com/contest/878/problem/E
tag是假的
(ans = sum_{i=1}^{n}a_i2^{k_i} ; ; 1 le k_i le k_{i-1}+1)
如果对于([l, r])是正的话从右往左加贪心
离线后从左往右加数
如果是负数那么单独成一块
否则就向前面的块合并
并查集维护一下块的答案
复杂度(O(nalpha (n)))
#include<bits/stdc++.h>
#define int long long
using namespace std;
template<typename tp> inline void read(tp &x) {
x = 0; char c = getchar(); int f = 0;
for(; c < '0' || c > '9'; f |= c == '-', c = getchar());
for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
if(f) x = -x;
}
namespace {
const int mo = 1e9 + 7;
const int inv2 = (mo + 1) / 2;
inline int add(int x, int y) {
if((x += y) >= mo) x -= mo;
if(x < 0) x += mo;
return x;
}
inline int sub(int x, int y) {
if((x -= y) < 0) x += mo;
if(x >= mo) x -= mo;
return x;
}
inline int mul(int x, int y) {
return x * y % mo;
}
inline int pw(int a, int k, int mo) {
int ans = 1;
for(; k; k >>= 1, a = mul(a, a))
if(k & 1) ans = mul(ans, a);
return ans;
}
}
const int N = 3e5 + 233;
const int LIM = 3e9 + 233;
struct Query {
int l, r, id, ans;
}q[N];
vector<Query> vec[N];
int ipw2[N], pw2[N], suf[N];
int pre[N], sum[N], st[N], ed[N], su[N];
int S[N], top = 0;
int n, m, ans[N], a[N];
inline int get(int l, int r) {
return mul(ipw2[l - 1], sub(suf[r], suf[l - 1]));
}
inline void init(void) {
pw2[0] = 1;
for(int i = 1; i < N; i ++)
pw2[i] = mul(pw2[i - 1], 2);
ipw2[0] = 1;
for(int i = 1; i < N; i ++)
ipw2[i] = mul(ipw2[i - 1], inv2);
for(int i = 1; i <= n; i ++) {
suf[i] = add(suf[i - 1], mul(a[i], pw2[i - 1]));
}
}
inline int find(int x) {
return pre[x] == x ? x : pre[x] = find(pre[x]);
}
inline void uni(void) {
int fx = S[top], fy = S[top - 1];
top -= 2;
pre[fy] = fx;
if(ed[fy] - st[fy] + 1 + log2(sum[fx]) >= 38) sum[fx] = LIM;
else {
sum[fx] <<= ed[fy] - st[fy] + 1;
sum[fx] += sum[fy];
if(sum[fx] >= LIM) sum[fx] = LIM;
}
st[fx] = st[fy];
S[++ top] = fx;
su[S[top]] = add(su[S[top - 1]], get(st[fx], ed[fx]));
}
inline int gao(int l) {
int fa = find(l);
int ans = 0;
ans = mul(2, sub(su[S[top]], su[fa]));
ans = add(ans, get(l, ed[fa]));
return ans;
}
inline void doit(void) {
for(int i = 1; i <= n; i ++) {
pre[i] = i, sum[i] = a[i];
st[i] = ed[i] = i;
}
for(int i = 1; i <= n; i ++) {
S[++ top] = i;
su[S[top]] = add(su[S[top - 1]], get(st[i], ed[i]));
while(top >= 2 && sum[find(S[top])] >= 0) {
uni();
}
for(auto t: vec[i]) {
ans[t.id] = gao(t.l);
}
}
}
main(void) {
read(n); read(m);
for(int i = 1; i <= n; i ++) {
read(a[i]);
}
init();
for(int i = 1; i <= m; i ++) {
read(q[i].l); read(q[i].r); q[i].id = i;
vec[q[i].r].push_back(q[i]);
}
doit();
for(int i = 1; i <= m; i ++)
cout << ans[i] << "
";
}
以上是关于贪心 codeforces 878E的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 1154D - Walking Robot - [贪心]