QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#24536 | #2560. Streetlights | nantf | WA | 19ms | 159648kb | C++20 | 8.1kb | 2022-03-31 14:58:22 | 2022-04-30 06:03:46 |
Judging History
answer
#include<bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
const int N = 1 << 18, INF = 0x3f3f3f3f;
int n, q, a[N], b[N], c[N], ans[N];
struct Wire { // compressed tree of electric wire (lef, rig)
int lef, rig, val, cnt;
Wire(int _1 = 0, int _2 = 0, int _3 = 0, int _4 = 0):
lef(_1), rig(_2), val(_3), cnt(_4){}
} wre[19][N], _wre[N];
struct Node { // compressed sequence
int lef, rig; bool spe;
Node(int _1 = 0, int _2 = 0, bool _3 = 0):
lef(_1), rig(_2), spe(_3){}
} nod[19][N];
namespace SegT { // magical Segment Tree
const int M = 1 << 17;
int mx[M<<1];
void upd(int p, int v){
// printf("upd(%d, %d)\n", p, v);
for(mx[p += M] = v, p >>= 1;p;p >>= 1)
mx[p] = max(mx[p<<1], mx[p<<1|1]);
}
int qryL(int p, int v){
for(p += M-1;(p & p-1) && mx[p] < v;p = p-1>>1);
if(mx[p] < v) return 0;
for(;p < M;p <<= 1, p |= mx[p|1] >= v);
return mx[p] == v ? p-M : 0;
}
int qryR(int p, int v){
// printf("qryR(%d, %d)\n", p, v);
for(p += M+1;(p & p+1) && mx[p] < v;p = p+1>>1);
if(mx[p] < v) return 0;
for(;p < M;p <<= 1, p |= mx[p] < v);
return mx[p] == v ? p-M : 0;
}
}
int rev[N]; // correspond index of the compressed sequence
int _b[19][N]; // temporary backup of array `b`
bool flg[N]; // is a key point in the virtual tree
bool vis[N];
int buc[N], pos[N], qwa[N], nsta[19][N], _nsta[19][N], tp;
int stk[N]; // index of monotonic stack
void krow(int dep, int nods, int &wres){
memcpy(nod[dep+1], nod[dep], (sizeof(Node)) * (nods + 1));
for(int i = 1;i <= nods;++ i)
if(nsta[dep][i]) nod[dep+1][i].spe = false;
static Wire hl[N], hr[N], buk[N];
int hls = 0;
auto useful = [&](int p){
if(!p) return 0;
int l = 1, r = nods, md;
while(l <= r){
md = l + r >> 1;
if(p < nod[dep][md].lef) r = md - 1;
else if(p > nod[dep][md].rig) l = md + 1;
else return md;
} return 0;
};
memset(vis, 0, nods + 1);
memset(buc, 0, nods + 2 << 2);
for(int i = 1;i <= nods;++ i) if(nsta[dep][i]){
int lef = useful(SegT::qryL(nod[dep][i].lef, nsta[dep][i]));
if(lef){
if(nsta[dep][lef]){
vis[lef] = true;
hr[lef] = Wire(lef, i, nsta[dep][i], 1);
} else hl[++hls] = Wire(lef, i, nsta[dep][i], 1);
}
}
for(int i = 1;i <= nods;++ i) if(nsta[dep][i] && !vis[i]){
int rig = useful(SegT::qryR(nod[dep][i].lef, nsta[dep][i]));
if(rig){hr[i] = Wire(i, rig, nsta[dep][i], 1); vis[i] = true;}
}
for(int i = 1;i <= hls;++ i) ++buc[hl[i].lef+1];
for(int i = 1;i <= nods;++ i) buc[i+1] += buc[i];
for(int i = 1;i <= hls;++ i) buk[++buc[hl[i].lef]] = hl[i];
memcpy(hl, buk, (sizeof(Wire)) * (hls + 1));
memset(flg, 0, wres + 1); tp = 0;
for(int i = 1, j = 1;i <= nods;++ i){
for(;tp && wre[dep][stk[tp]].rig == i;-- tp);
for(;j <= wres && wre[dep][j].lef == i;++ j)
stk[++tp] = j;
for(;tp && wre[dep][stk[tp]].val <= nsta[dep][i];-- tp)
flg[stk[tp]] = true;
}
int ps[3] = {1, 1, 1}, nwres = 0;
while(true){
while(ps[1] <= nods && !vis[ps[1]]) ++ ps[1];
while(ps[2] <= wres && flg[ps[2]]) ++ ps[2];
if(ps[0] > hls && ps[1] > nods && ps[2] > wres)
break;
pii pv0 = ps[0] <= hls ? MP(hl[ps[0]].lef, -hl[ps[0]].rig) : MP(INF, INF),
pv1 = ps[1] <= nods ? MP(hr[ps[1]].lef, -hr[ps[1]].rig) : MP(INF, INF),
pv2 = ps[2] <= wres ? MP(wre[dep][ps[2]].lef, -wre[dep][ps[2]].rig) : MP(INF, INF),
pv_ = min(pv0, min(pv1, pv2));
if(pv0 == pv_) wre[dep+1][++nwres] = hl[ps[0]++];
else if(pv1 == pv_) wre[dep+1][++nwres] = hr[ps[1]++];
else wre[dep+1][++nwres] = wre[dep][ps[2]++];
}
wres = nwres;
}
struct PathV { // vertex of path from root when dfs on the tree
int id, rig, val;
PathV(int _1 = 0, int _2 = 0, int _3 = 0):
id(_1), rig(_2), val(_3){}
} pat[N];
void work(int dep, int ql, int qr, int nods, int wres, int nans){
// printf("ql = %d, qr = %d, nods = %d, wres = %d\n", ql, qr, nods, wres);
// for(int i = 1;i <= wres;++ i)
// printf("wre[%d] = %d, %d, %d, %d\n", i, wre[dep][i].lef, wre[dep][i].rig, wre[dep][i].val, wre[dep][i].cnt);
if(ql == qr){
// printf("b[%d] = %d, c[%d] = %d\n", ql, b[ql], ql, c[ql]);
if(SegT::qryL(nod[dep][b[ql]].lef, c[ql])) ++ nans;
// printf("nans = %d\n", nans);
if(SegT::qryR(nod[dep][b[ql]].lef, c[ql])) ++ nans;
// printf("nans = %d\n", nans);
for(int i = 1;i <= wres;++ i)
if(wre[dep][i].rig < b[ql] || wre[dep][i].lef > b[ql] || wre[dep][i].val > c[ql])
nans += wre[dep][i].cnt;
ans[ql] = nans; return;
}
int md = ql + qr >> 1, _ = 0;
for(int i = 1;i <= nods;++ i){
if(_ && !nod[dep][i].spe && !nod[dep][_].spe)
nod[dep][_].rig = nod[dep][i].rig;
else
nod[dep][++_] = nod[dep][i];
rev[i] = _;
}
nods = _; _ = 0;
// for(int i = 1;i <= nods;++ i)
// printf("nod[%d] = %d, %d, %d\n", i, nod[dep][i].lef, nod[dep][i].rig, nod[dep][i].spe);
memcpy(_b[dep] + ql, b + ql, qr - ql + 1 << 2);
for(int i = ql;i <= qr;++ i) b[i] = rev[b[i]];
for(int i = 1;i <= wres;++ i){
wre[dep][i].lef = rev[wre[dep][i].lef];
wre[dep][i].rig = rev[wre[dep][i].rig];
if(wre[dep][i].lef == wre[dep][i].rig)
nans += wre[dep][i].cnt;
else
wre[dep][++_] = wre[dep][i];
}
wres = _; _ = 0;
memset(buc, 0, nods + 2 << 2);
memset(flg, 0, wres + 1);
for(int i = ql;i <= qr;++ i) ++ buc[b[i]+1];
for(int i = 1;i <= nods;++ i) buc[i+1] += buc[i];
for(int i = ql;i <= qr;++ i) qwa[++buc[b[i]]] = c[i];
tp = 0;
auto useful = [&](int val){
if(val < pat[tp].val) return 0;
int L = 1, R = tp, md;
while(L < R) pat[md = L+R>>1].val <= val ? R = md : L = md+1;
return pat[L].id;
};
for(int i = 1, j = 1;i <= nods;++ i){
for(;tp && pat[tp].rig <= i;-- tp);
for(;j <= wres && wre[dep][j].rig <= i;++ j)
pat[++tp] = PathV(j, wre[dep][j].rig, wre[dep][j].val);
if(nod[dep][i].spe) flg[useful(a[nod[dep][i].lef])] = true;
for(int k = buc[i-1]+1;k <= buc[i];++ k)
flg[useful(qwa[k])] = true;
}
_wre[_ = 1] = wre[dep][1];
for(int i = 2;i <= wres;++ i)
if(!flg[i] && wre[dep][i].lef == _wre[_].lef && wre[dep][i].rig == _wre[_].rig)
_wre[_].cnt += wre[dep][i].cnt;
else
_wre[++_] = wre[dep][i];
memcpy(wre[dep], _wre, (sizeof(Wire)) * (_ + 1)); wres = _;
memset(nsta[dep], 0, nods + 1 << 2);
for(int i = 1;i <= nods;++ i)
if(nod[dep][i].spe) nsta[dep][i] = a[nod[dep][i].lef];
for(int i = ql;i <= md;++ i) nsta[dep][b[i]] = 0;
for(int i = 1;i <= nods;++ i)
if(nsta[dep][i]) SegT::upd(nod[dep][i].lef, nsta[dep][i]);
krow(dep, nods, _ = wres);
work(dep + 1, ql, md, nods, _, nans);
// ------------------------------
for(int i = 1;i <= nods;++ i)
if(nsta[dep][i]) SegT::upd(nod[dep][i].lef, 0);
memset(nsta[dep], 0, nods + 1 << 2);
for(int i = ql;i <= md;++ i)
nsta[dep][b[i]] = c[i];
for(int i = 1;i <= nods;++ i) if(nod[dep][i].spe){
_nsta[dep][i] = a[nod[dep][i].lef];
if(nsta[dep][i]) a[nod[dep][i].lef] = nsta[dep][i];
}
for(int i = md+1;i <= qr;++ i) nsta[dep][b[i]] = 0;
for(int i = 1;i <= nods;++ i)
if(nsta[dep][i]) SegT::upd(nod[dep][i].lef, nsta[dep][i]);
krow(dep, nods, _ = wres);
work(dep + 1, md+1, qr, nods, _, nans);
// -------------------------------
for(int i = 1;i <= nods;++ i) if(nod[dep][i].spe){
a[nod[dep][i].lef] = _nsta[dep][i];
if(nsta[dep][i]) SegT::upd(nod[dep][i].lef, 0);
}
memcpy(b + ql, _b[dep] + ql, qr - ql + 1 << 2);
}
bitset<N> nst; // non-static
int main(){
// freopen("a.in", "r", stdin);
ios::sync_with_stdio(false);
cin >> n >> q; //n += 2;
for(int i = 1;i <= n;++ i) cin >> a[i];
for(int i = 1;i <= q;++ i) cin >> b[i] >> c[i];
int wres = 0;
for(int i = 1;i <= q;++ i) nst.set(b[i]);
for(int i = 1;i <= n;++ i) if(!nst.test(i)){
for(;tp && a[stk[tp]] < a[i];-- tp);
if(tp && a[stk[tp]] == a[i]){
wre[0][++wres] = Wire(stk[tp], i, a[i], 1);
-- tp;
}
stk[++tp] = i;
SegT::upd(i, a[i]);
}
for(int i = 1;i <= n;++ i) nod[0][i] = Node(i, i, nst.test(i));
tp = 0;
for(int i = 1;i <= n;++ i){
for(;tp && a[stk[tp]] < a[i];-- tp);
if(tp && a[stk[tp]] == a[i]){
++ ans[0]; -- tp;
}
stk[++tp] = i;
}
work(0, 1, q, n, wres, 0);
for(int i = 0;i <= q;++ i)
printf("%d\n", ans[i]);
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 19ms
memory: 159528kb
input:
6 2 4 2 2 2 4 6 4 6 6 4
output:
3 2 2
result:
ok 3 lines
Test #2:
score: -100
Wrong Answer
time: 12ms
memory: 159648kb
input:
50 100 310081863 722273055 654741011 310081863 654741011 722273055 654741011 722273055 654741011 654741011 654741011 310081863 310081863 722273055 654741011 654741011 654741011 722273055 310081863 654741011 310081863 310081863 310081863 722273055 310081863 654741011 654741011 310081863 722273055 722...
output:
28 42 42 47 49 47 47 47 42 42 42 42 42 43 40 41 43 42 40 40 41 36 36 35 35 35 41 41 42 44 39 38 36 37 37 40 41 41 40 31 30 29 30 28 31 31 32 32 32 33 32 37 39 40 39 37 36 35 35 33 34 35 33 33 38 37 38 37 37 37 38 38 36 37 36 34 30 31 29 29 28 28 28 28 28 28 27 28 30 28 29 30 29 29 29 30 30 30 28 29 28
result:
wrong answer 2nd lines differ - expected: '28', found: '42'