Topic links
Test instructions: Given a sequence, there are two kinds of operations
Operation 1, Interval weighting
Operation 2, the maximum distance of the number of a[i] = = y in the query sequence
That
for (int i = 0; i < n; i++) if (a[i] = = y) L = i, break;
for (int i = n-1; I >= 0; i--) if (a[i]==y) r=i, break;
Put (R-L);
Idea: chunking.
Introduce the idea of chunking
Divide the interval into x blocks, then each block length is n/x (if n/x cannot be divisible then the last piece length is n%x)
Set Y as interval length, i.e. y=n/x;
We guarantee that each block of the interval is orderly , that is, all modifications must be ordered.
Set a global offset for each interval long B;
Action 1:
Query all blocks that intersect [l,r]:
If (this piece is fully covered by [l,r])
B+=val;
Else
{
Violence modification:
Violent enumeration of all elements in this block, if this element belongs to [l,r] then this element +=val
A sequence for this piece
(obviously only 2 blocks of the boundary will not be fully covered.)
}
Action 2:
Query each piece, because the block is ordered, so two minutes is good.
Computational complexity:
For Action 1:
The maximum number of query blocks is x, and the complexity of brute force modification is O (Y*log (y))
So the complexity of Operation 1 is O (x + y*log (y))
For Action 2:
The number of query blocks is x, and the elements inside the lookup block are two points: log (y)
So the complexity of Operation 2 is O (x * log (Y))
We want to make O (max (x + ylog (y), Xlog (y)) as small as possible
According to the basic inequality, the minimum when x==y
= = n = x*y; X=Y=SQRT (n);
That is, the sequence is divided into sqrt (n) blocks, each with a size of sqrt (n)
#include <iostream> #include <string> #include <vector> #include <cstring> #include <cstdio > #include <map> #include <queue> #include <algorithm> #include <stack> #include <cstring > #include <cmath> #include <set> #include <vector>using namespace std;template <class t> inline BOOL Rd (T &ret) {char c; int sgn;if (c = GetChar (), c = = EOF) return 0;while (c! = '-' && (c< ' 0 ' | | C> ' 9 ')) C = GetChar (); sgn = (c = = '-')? -1:1;ret = (c = = '-')? 0: (C-' 0 '); while (c = GetChar (), C >= ' 0 ' &&c <= ' 9 ') ret = ret * + (C-' 0 '); ret *= Sgn;return 1;} Template <class t>inline void pt (T x) {if (x < 0) {Putchar ('-'); x =-X;} if (x > 9) pt (X/10);p Utchar (x% 10 + ' 0 ');} typedef long Long Ll;typedef pair<ll, int> pii;const int inf = 1e9;const int N = 5e5 + 10;const int Block = 850;//70 0int N, Q;int ansl, ansr;ll a[n];set<pii>::iterator it;struct Node {set<pii>x;ll b;inline void Add (int l, int r, int val) {if (r-l + 1 = = (int) x.size ()) B + = Val;else {for (int i = l; I <= R; i++) {X.erase ({A[i], i}); A[i] + = Val;x.insert ({a[i], i});}}} inline void find (ll y) {y-= B;it = X.lower_bound ({y,-inf}); if (it = = X.end () | | (*it). First! = y) return;ansl = min (Ansl, (*it). second); it = X.upper_bound ({y, inf}); IT--;ANSR = Max (ANSR, (*it). second);}} Y[block];int Block;int Main () {rd (n); Rd (q); for (int i = 0; i < n; i++) Rd (A[i]); Block = 0;for (int i = 0; i < n; i + = block, block++) for (int j = 0; i + J < n && J < Block; J + +) {Y[block].x.insert ({a[i + j],i + j});} int op, L, R, Val;while (q--) {Rd (OP); if (op = = 1) {rd (L); Rd (R); Rd (Val); l--;r--;for (int i = l/block; I <= r/block ; i++) Y[i].add (Max (L, I*block), Min (R, I*block + Block-1), Val);} else {Rd (val); ansl = inf, ANSR =-inf;for (int i = 0; i < block; i++) Y[i].find (val); if (Ansr-ansl < 0) puts ("1"); E LSE PT (ANSR-ANSL), Putchar (' \ n ');}} return 0;}
Get rid of the set. :
#include <iostream> #include <string> #include <vector> #include <cstring> #include <cstdio > #include <map> #include <queue> #include <algorithm> #include <stack> #include <cstring > #include <cmath> #include <set> #include <vector>using namespace std;template <class t> inline BOOL Rd (T &ret) {char c; int sgn;if (c = GetChar (), c = = EOF) return 0;while (c! = '-' && (c< ' 0 ' | | C> ' 9 ')) C = GetChar (); sgn = (c = = '-')? -1:1;ret = (c = = '-')? 0: (C-' 0 '); while (c = GetChar (), C >= ' 0 ' &&c <= ' 9 ') ret = ret * + (C-' 0 '); ret *= Sgn;return 1;} Template <class t>inline void pt (T x) {if (x < 0) {Putchar ('-'); x =-X;} if (x > 9) pt (X/10);p Utchar (x% 10 + ' 0 ');} typedef long Long Ll;typedef pair<int, int> pii;const int inf = 1e9;const int N = 5e5 + 10;const int Block = 850;//7 00int N, Q;int ansl, ansr;struct Node {struct point {ll A; int id; Point (ll _a = 0, ll _id = 0): A (_a), ID (_id) {}bool operator< (const point&x) const {if (x.a! = a) return a < X.a;return ID < x.id;}} X[block], tmp;ll b;int top;inline void sort () {sort (x, x + top);} inline void Add (int l, int r, int val) {if (r-l + 1 = = top) b + = Val;else {for (int i = 0; i < top; i++) if (l <= x[ I].id && x[i].id <= r) x[i].a + = val; Sort ();}} inline void find (ll y) {y-= b;if (Y < x[0].a | | x[top-1].a < y) return;tmp = {y,-inf};int L = lower_bound (x, X + Top, TMP)-x;if (L = = Top | | x[l].a! = y) return;tmp.id = inf;int r = Lower_bound (x, x + Top, tmp)-x-1;ansl = min (an SL, x[l].id); ANSR = max (ANSR, x[r].id);}} Y[block];int A[n], Block;int Main () {rd (N); Rd (q); for (int i = 0; i < N; i++) Rd (A[i]); Block = 0;for (int i = 0; i < N i + = block, block++) {for (int j = 0; i + J < N && J < Block; J + +) {y[block].x[j].a = A[i + j];y[block].x[j]. id = i + j;y[block].top++;} Y[block]. Sort ();} int op, L, R, Val;while (q--) {Rd (OP); if (op = = 1) {rd (L); Rd (R); RD (VAl); l--;r--;for (int i = l/block; I <= r/block; i++) Y[i].add (Max (L, I*block), Min (R, I*block + Block-1), Val);} else {Rd (val); ansl = inf, ANSR =-inf;for (int i = 0; i < block; i++) Y[i].find (val); if (Ansr-ansl < 0) puts ("1"); E LSE PT (ANSR-ANSL), Putchar (' \ n ');}} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Codeforces 551E Gukiz and Gukiziana tiles