QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#864287 | #9986. Shiori | ucup-team5243 | RE | 1ms | 3712kb | C++17 | 9.5kb | 2025-01-20 13:58:01 | 2025-01-20 13:58:01 |
Judging History
answer
#include <bits/stdc++.h>
namespace nachia{
template<
class S,
class F,
S op(S l, S r),
F composition(F f, F x),
S mapping(F f, S x)
>
struct LazySegtree {
private:
struct Node { S s; F f; bool propagated; };
int N;
int logN;
int xN;
std::vector<Node> A;
void mapf(Node& a, F f){
a.propagated = false;
a.f = composition(f, a.f);
a.s = mapping(f, a.s);
}
void mergev(int i){
if(i<N) A[i].s = op(A[i*2].s, A[i*2+1].s);
}
void spread(int i){
if(A[i].propagated || !(i < N)) return;
mapf(A[i*2], A[i].f);
mapf(A[i*2+1], A[i].f);
A[i].f = A[0].f;
A[i].propagated = true;
}
// bool cmp(S)
template<class E>
int minLeft2(int r, E cmp, int a = 0, int b = 0, int i = -1){
static S x;
if(i == -1){ a=0; b=N; i=1; x = A[0].s; }
if(r <= a) return a;
if(b <= r){
S nx = op(A[i].s, x);
if(cmp(nx)){ x = nx; return a; }
}
if(b-a == 1) return b;
spread(i);
int q = minLeft2(r, cmp, (a+b)/2, b, i*2+1);
if(q > (a+b)/2) return q;
return minLeft2(r, cmp, a, (a+b)/2, i*2);
}
// bool cmp(S)
template<class E>
int maxRight2(int l, E cmp, int a = 0, int b = 0, int i = -1){
static S x;
if(i == -1){ a=0; b=N; i=1; x = A[0].s; }
if(b <= l) return b;
if(l <= a){
S nx = op(x, A[i].s);
if(cmp(nx)){ x = nx; return b; }
}
if(b - a == 1) return a;
spread(i);
int q = maxRight2(l, cmp, a, (a+b)/2, i*2);
if(q < (a+b)/2) return q;
return maxRight2(l, cmp, (a+b)/2, b, i*2+1);
}
public:
LazySegtree() : N(0), logN(-1), xN(0){}
LazySegtree(int n, S e, F id){
N=1; logN=0; xN=n;
while(N<n){ N *= 2; logN++; }
A.assign(N*2, { e, id, true });
}
LazySegtree(const std::vector<S>& a, S e, F id)
: LazySegtree(a.size(), std::move(e), std::move(id)){
for(std::size_t i=0; i<a.size(); i++) A[i+N].s = a[i];
for(int i=N-1; i>=1; i--) mergev(i);
}
void set(int p, S x){
p += N;
for(int d=logN; d; d--) spread(p >> d);
A[p].s = x;
for(int d=1; d<=logN; d++) mergev(p >> d);
}
S get(int p){
p += N;
for(int d=logN; d; d--) spread(p >> d);
return A[p].s;
}
void apply(int p, F f){ set(p, mapping(f, get(p))); }
void apply(int l, int r, F f){
if(!(l < r)) return;
if(l == 0 && r == N){ mapf(A[1], f); return; }
l += N; r += N;
for(int d=logN; d; d--){
if((l >> d) << d != l) spread(l >> d);
if((r >> d) << d != r) spread(r >> d);
}
int lp = l, rp = r;
while(l < r){
if(l&1){ mapf(A[l++], f); } l /= 2;
if(r&1){ mapf(A[--r], f); } r /= 2;
}
for(int d=1 ; d<=logN; d++){
if((lp >> d) << d != lp) mergev(lp >> d);
if((rp >> d) << d != rp) mergev(rp >> d);
}
}
S prod(int l, int r){
if(!(l < r)) return A[0].s;
l += N; r += N;
for(int d=logN; d; d--){
if((l >> d) << d != l) spread(l >> d);
if((r >> d) << d != r) spread(r >> d);
}
S q1 = A[0].s, q2 = A[0].s;
while(l < r){
if(l&1){ q1 = op(q1, A[l++].s); } l /= 2;
if(r&1){ q2 = op(A[--r].s, q2); } r /= 2;
}
return op(q1, q2);
}
S allProd() const { return A[1].s; }
// bool cmp(S)
template<class E>
int minLeft(int r, E cmp){
return minLeft2(r, cmp);
}
// bool cmp(S)
template<class E>
int maxRight(int l, E cmp){
int x = maxRight2(l, cmp);
return x > xN ? xN : x;
}
};
} // namespace nachia;
namespace nachia {
template<class S>
struct RangeAddRangeMin{
private:
static std::pair<S,int> minop(std::pair<S,int> l, std::pair<S,int> r){ return std::min(l, r); }
static std::pair<S,int> addop(S f, std::pair<S,int> x){ return {f+x.first,x.second}; }
static S addop2(S f, S x){ return f+x; }
using Base = LazySegtree<std::pair<S,int>, S, minop, addop2, addop>;
Base base;
public:
RangeAddRangeMin() {}
RangeAddRangeMin(const std::vector<std::pair<S,int>>& init, S INF, S ZERO)
: base(init, {INF,-1}, ZERO){}
std::pair<S,int> min(int l, int r){ return base.prod(l, r); }
std::pair<S,int> min(){ return base.allProd(); }
void add(int l, int r, S val){ base.apply(l, r, val); }
void set(int p, S val){ base.set(p, {val,p}); }
S get(int p){ return base.get(p).first; }
};
} // namespace nachia
namespace nachia{
struct WordsizeTree{
using Word = unsigned long long;
static constexpr int W = 64;
int N;
std::vector<std::vector<Word>> A;
static int highBit(Word x){
if(x == 0) return 0;
return W-1 - __builtin_clzll(x);
}
static int lowBit(Word x){
if(x == 0) return W;
return __builtin_ctzll(x);
}
WordsizeTree(int length){
N = length;
int n = length;
do {
std::vector<Word> a(n/W+1,0);
A.emplace_back(std::move(a));
n /= W;
} while(n);
}
WordsizeTree(const std::string& binStr = ""){
N = binStr.size();
int n = N;
{
std::vector<Word> a(n/W+1);
for(int i=0; i<n; i++) if(binStr[i] == '1'){
a[i/W] |= (Word)1 << (i%W);
}
A.emplace_back(std::move(a));
n /= W;
}
while(n){
std::vector<Word> a(n/W+1,0);
for(int i=0; i<=n; i++){
if(A.back()[i]) a[i/W] |= (Word)1 << (i%W);
}
A.emplace_back(std::move(a));
n /= W;
}
}
void insert(int x){
for(auto& a : A){
a[x/W] |= (Word)1 << (x % W);
x /= W;
}
}
void erase(int x){
for(auto& a : A){
a[x/W] &= ~((Word)1 << (x % W));
if(a[x/W]) return;
x /= W;
}
}
int count(int x) const {
return (int)((A[0][x/W] >> (x%W)) & 1);
}
int noLessThan(int x) const {
if(x < 0) x = 0;
if(N <= x) return N;
int d = 0, i = x;
while(true){
if(d >= (int)A.size()) return N;
if(i/W >= (int)A[d].size()) return N;
Word m = A[d][i/W] & ((~(Word)0) << (i%W));
if(!m){ d++; i /= W; i++; }
else{
int to = lowBit(m);
i = i/W*W + to;
if(d == 0) break;
i *= W;
d--;
}
}
return i;
}
int noGreaterThan(int x) const {
if(x < 0) return -1;
if(N <= x) x = N-1;
int d = 0, i = x;
while(true){
if(i < 0) return -1;
if(d >= (int)A.size()) return -1;
Word m = A[d][i/W] & ~((~(Word)1) << (i%W));
if(!m){ d++; i /= W; i--; }
else{
int to = highBit(m);
i = i/W*W + to;
if(d == 0) break;
i *= W;
i += W-1;
d--;
}
}
return i;
}
};
} // namespace nachia
using namespace std;
using i64 = long long;
#define rep(i,n) for(i64 i=0; i<(i64)(n); i++)
namespace RangeAddRangeSetRangeSum {
struct S{ i64 x; i64 c; };
struct F{ i64 a; i64 s; };
S op(S l, S r){ return {l.x+r.x,l.c+r.c}; }
S mapping(F f, S x){
if(f.s != -1) return {(f.s+f.a)*x.c,x.c};
return {x.x+f.a*x.c,x.c};
}
F composition(F f, F x){
if(f.s != -1) return f;
return { f.a+x.a, x.s };
}
using Ds = nachia::LazySegtree<S, F, op, composition, mapping>;
};
void testcase(){
const i64 INF = 1001001001001001001;
i64 N, Q; cin >> N >> Q;
nachia::WordsizeTree border(string(N, '1'));
vector<i64> A(N); rep(i,N) cin >> A[i];
vector<pair<i64,int>> A1(N); rep(i,N){ A1[i] = {A[i],i}; }
vector<RangeAddRangeSetRangeSum::S> A2(N); rep(i,N){ A2[i] = {A[i],1}; }
nachia::RangeAddRangeMin<i64> ds(A1, INF, 0);
RangeAddRangeSetRangeSum::Ds dss(A2, {0,0}, {0,-1});
auto add = [&](i64 l, i64 r, i64 val) -> void {
ds.add(l,r,val);
dss.apply(l,r,{val,-1});
};
auto split = [&](i64 p){
i64 l = border.noGreaterThan(p);
if(l == p) return;
ds.set(p, ds.get(l));
border.insert(p);
};
rep(qi,Q){
int ty; cin >> ty;
if(ty == 1){
i64 l,r,v; cin >> l >> r >> v; l--; split(l); split(r);
dss.apply(l,r,{0,v});
for(i64 p=border.noLessThan(l+1); p<r; p=border.noLessThan(l+1)){
border.erase(p); ds.set(p,INF); }
ds.set(l,v);
} else if(ty==2){
i64 l,r; cin >> l >> r; l--; split(l); split(r);
i64 ex = 0;
vector<pair<i64,int>> buf;
while(true){
auto [v,p] = ds.min(l,r);
if(ex < v) break;
buf.push_back({v,p}); ds.set(p,INF);
ex = v + 1;
}
//cout << "mex = " << ex << endl;
for(auto [v,p] : buf) ds.set(p,v);
add(l,r,ex);
} else {
i64 l,r; cin >> l >> r; l--;
cout << dss.prod(l,r).x << "\n";
}
}
}
int main(){
cin.tie(nullptr); ios::sync_with_stdio(false);
testcase();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 3712kb
input:
5 8 0 7 2 1 0 1 2 4 0 2 1 3 2 3 4 3 1 3 1 2 3 4 3 1 4 2 1 5 3 2 5
output:
5 11 22
result:
ok 3 number(s): "5 11 22"
Test #2:
score: -100
Runtime Error
input:
1 1 0 1 1 1 0