QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#24550#2560. StreetlightsnantfWA 25ms159716kbC++208.7kb2022-03-31 16:14:242022-04-30 06:04:40

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-04-30 06:04:40]
  • 评测
  • 测评结果:WA
  • 用时:25ms
  • 内存:159716kb
  • [2022-03-31 16:14:24]
  • 提交

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/*, printf("delete (%d, %d, %d)\n", wre[dep][stk[tp]].lef, wre[dep][stk[tp]].rig, wre[dep][stk[tp]].val)*/;
	}
	int ps[3] = {1, 1, 1}, nwres = 0;
//	printf("wres = %d\n", wres);
	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, nans = %d\n", ql, qr, nods, wres, nans);
//	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;
		if(SegT::qryR(nod[dep][b[ql]].lef, c[ql])) ++ 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;
//		printf("nans = %d\n", nans);
		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){
//		printf("val = %d\n", 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;
//		printf("pat[%d].id = %d\n", L, pat[L].id);
		return pat[L].id;
	};
//	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);
	for(int i = 1, j = 1;i <= nods;++ i){
		for(;tp && pat[tp].rig <= i;-- tp);
		for(;j <= wres && wre[dep][j].lef <= i;++ j)
			pat[++tp] = PathV(j, wre[dep][j].rig, wre[dep][j].val)/*, printf("%d : add (%d, %d, %d)\n", i, 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 = _;
//	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);
	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);
//	freopen("a.out", "w", stdout);
	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 = n;i;-- i) if(!nst.test(i)){
		for(;tp && a[stk[tp]] < a[i];-- tp);
		if(tp && a[stk[tp]] == a[i]){
			wre[0][++wres] = Wire(i, stk[tp], a[i], 1);
			-- tp;
		}
		stk[++tp] = i;
		SegT::upd(i, a[i]);
	}
	reverse(wre[0] + 1, wre[0] + wres + 1);
	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]);
}

詳細信息

Test #1:

score: 100
Accepted
time: 3ms
memory: 159576kb

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: 25ms
memory: 159716kb

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
28
28
29
30
31
31
31
31
31
31
31
31
32
34
35
35
34
34
34
33
32
32
31
31
31
32
32
31
31
31
31
30
30
30
31
31
31
31
31
31
30
30
29
30
31
32
32
32
32
32
31
32
33
33
33
33
32
32
31
32
33
31
31
32
31
32
31
31
31
30
31
30
29
29
28
28
29
28
28
27
27
27
27
27
27
26
27
28
27
28
29
28
28
28
28
29
29
28
29
28

result:

wrong answer 15th lines differ - expected: '33', found: '34'