├── Etc └── fio.cpp ├── Geometry ├── ccw.cpp ├── circle.cpp ├── graham's_scan.cpp ├── point.cpp ├── readme.txt └── rotating_calipers.cpp ├── Graph ├── Dinic.cpp ├── Hk.cpp ├── mcmf.cpp ├── readme.txt └── scc.cpp ├── Math ├── extended_euclidean.cpp ├── fft.cpp ├── ntt.cpp └── readme.txt ├── Sqrt ├── Sqrtdecomposition.cpp └── readme.txt ├── Stl ├── map.cpp ├── pq.cpp ├── queue.cpp ├── readme.txt ├── set.cpp ├── sort.cpp ├── stack.cpp └── vector.cpp ├── String ├── kmp.cpp ├── lcparray.cpp ├── readme.txt └── suffixarray.cpp └── Tree ├── 2dIndextree.cpp ├── 2dSegmenttree.cpp ├── Indextree.cpp ├── LazyIndextree.cpp ├── Lazypropagation.cpp ├── Treap.cpp ├── readme.txt └── splay_tree.cpp /Etc/fio.cpp: -------------------------------------------------------------------------------- 1 | namespace fio { 2 | const int BSIZE = 524288; 3 | unsigned char buffer[BSIZE]; 4 | auto p = buffer + BSIZE; 5 | inline unsigned char readChar() { 6 | if (p == buffer + BSIZE) { 7 | fread(buffer,1,BSIZE,stdin); 8 | p = buffer; 9 | } 10 | return *p++; 11 | } 12 | int readInt() { 13 | unsigned char c = readChar(); 14 | while (c < '-') { 15 | c = readChar(); 16 | } 17 | int ret = 0; 18 | while (c >= '-') { 19 | ret = ret * 10 + c - '0'; 20 | c = readChar(); 21 | } 22 | return ret; 23 | } 24 | } -------------------------------------------------------------------------------- /Geometry/ccw.cpp: -------------------------------------------------------------------------------- 1 | //원점 기준 b가 a의 반시계 > 0, 시계 < 0, 평행 = 0 2 | int ccw(point a, point b){ 3 | double ret=a.cross(b); 4 | if(ret<0) 5 | return -1; 6 | if(ret>0) 7 | return 1; 8 | return 0; 9 | } 10 | 11 | //p 기준 b가 a의 반시계 > 0, 시계 < 0, 평행 = 0 12 | int ccw(point p, point a, point b){ 13 | return ccw(a-p, b-p); 14 | } 15 | -------------------------------------------------------------------------------- /Geometry/circle.cpp: -------------------------------------------------------------------------------- 1 | 2 | point RotateCCW90(point p) { return point(-p.y,p.x); } 3 | 4 | vector CircleCircleIntersection(point a, point b, double r, double R) { 5 | vector ret; 6 | double d = (a-b).norm(); 7 | if (d > r+R || d+min(r, R) < max(r, R)) return ret; 8 | double x = (d*d-R*R+r*r)/(2*d); 9 | double y = sqrt(r*r-x*x); 10 | point v = (b-a)/d; 11 | ret.push_back(a+v*x + RotateCCW90(v)*y); 12 | if (y > 0) 13 | ret.push_back(a+v*x - RotateCCW90(v)*y); 14 | return ret; 15 | } -------------------------------------------------------------------------------- /Geometry/graham's_scan.cpp: -------------------------------------------------------------------------------- 1 | // O(nlgn) convex hull 2 | vector graham(vector& input){ 3 | int n = input.size(); 4 | vector hull; 5 | vector up(n), down(n); 6 | int iup, idown; 7 | iup = idown = -1; 8 | sort(input.begin(), input.end()); 9 | for(int i=0;i0&&ccw(up[iup-1], up[iup], input[i])>=0) 11 | iup--; 12 | up[++iup]=input[i]; 13 | while(idown>0&&ccw(down[idown-1], down[idown], input[i])<=0) 14 | idown--; 15 | down[++idown]=input[i]; 16 | } 17 | for(int i=0;i<=iup;i++) 18 | hull.push_back(up[i]); 19 | for(int i=idown-1;i>0;i--) 20 | hull.push_back(down[i]); 21 | return hull; 22 | } 23 | -------------------------------------------------------------------------------- /Geometry/point.cpp: -------------------------------------------------------------------------------- 1 | const double PI = 2.0 * acos(0.0); 2 | 3 | struct point{ 4 | typedef long long T; 5 | T x, y; 6 | point(){} 7 | point(T x, T y) :x(x), y(y) {} 8 | bool operator == (const point& rhs)const { 9 | return x == rhs.x&&y == rhs.y; 10 | } 11 | bool operator < (const point& rhs)const { 12 | return x != rhs.x ? x < rhs.x : y < rhs.y; 13 | } 14 | point operator + (const point&rhs)const { 15 | return point(x + rhs.x, y + rhs.y); 16 | } 17 | point operator - (const point&rhs)const { 18 | return point(x - rhs.x, y - rhs.y); 19 | } 20 | point operator * (T rhs)const { 21 | return point(x*rhs, y*rhs); 22 | } 23 | // 벡터의 길이 24 | double norm() const { 25 | return hypot(x,y); 26 | } 27 | // 단위 벡터 28 | point normalize() const { 29 | return point(x / norm(), y / norm()); 30 | } 31 | // x축의 양의 방 향으로부터 이 벡터까지 반시계 방향으로 잰 각도 32 | double polar() const { 33 | return fmod(atan2(y, x)+2*PI, 2*PI); 34 | } 35 | //내적 36 | T dot(const point&rhs)const { 37 | return x*rhs.x + y*rhs.y; 38 | } 39 | //외적 40 | T cross(const point&rhs)const { 41 | return x*rhs.y - rhs.x*y; 42 | } 43 | }; 44 | 45 | //수직이등분선 <점,방향벡터> 46 | pair perpendicular_bisector(const point &a, const point &b) { 47 | point c = b - a; 48 | return make_pair(point((a.x + b.x) / 2, (a.y + b.y) / 2), point(c.y, -c.x)); 49 | } 50 | //두 직선의 교점 리턴 51 | point intersection_point(const point &a, const point &b, const point &c, const point &d) { 52 | double det = b.cross(d); 53 | return a + b*((c - a).cross(d) / det); 54 | } 55 | //세 점의 외접원의 중점 구하기 56 | point circumscribed_circle(const point &p, const point &a, const point &b) { 57 | pair pa = perpendicular_bisector(p, a); 58 | pair pb = perpendicular_bisector(p, b); 59 | return intersection_point(pa.first, pa.second, pb.first, pb.second); 60 | } 61 | -------------------------------------------------------------------------------- /Geometry/readme.txt: -------------------------------------------------------------------------------- 1 | 교차판별, 내부판별, 넓이 구하기, 점에서 직선 수선의 발 2 | 원과 직선의 교점 3 | 각도 정렬 4 | -------------------------------------------------------------------------------- /Geometry/rotating_calipers.cpp: -------------------------------------------------------------------------------- 1 | double dist(point a, point b){ 2 | return hypot(a.x-b.x, a.y-b.y); 3 | } 4 | double calipus(const vector& p){ 5 | int n = p.size(); 6 | double ret=-1; 7 | int j=1; 8 | for(int i=0;i > adj; 16 | vector level; 17 | vector idx; 18 | Dinic(int n):n(n){ 19 | level=vector(n); 20 | idx=vector(n); 21 | adj=vector > (n); 22 | } 23 | ~Dinic(){ 24 | for(int i=0;irev=vu; 32 | vu->rev=uv; 33 | adj[u].push_back(uv); 34 | adj[v].push_back(vu); 35 | } 36 | bool bfs(int s, int t){ 37 | fill(level.begin(), level.end(), -1); 38 | level[s]=0; 39 | queue q; 40 | q.push(s); 41 | while(!q.empty()){ 42 | int now=q.front(); 43 | q.pop(); 44 | for(int i=0;iv; 46 | int sub=adj[now][i]->residual(); 47 | if(level[there]==-1&&sub>0){ 48 | level[there]=level[now]+1; 49 | q.push(there); 50 | } 51 | } 52 | } 53 | return level[t]==-1; 54 | } 55 | int dfs(int now, int t, int amount){ 56 | if(now==t) 57 | return amount; 58 | for(int &i=idx[now];iv; 60 | int sub=adj[now][i]->residual(); 61 | if(level[there]==level[now]+1&&sub>0){ 62 | int temp=dfs(there, t, min(amount, sub)); 63 | if(temp>0){ 64 | adj[now][i]->flow+=temp; 65 | adj[now][i]->rev->flow-=temp; 66 | return temp; 67 | } 68 | } 69 | } 70 | return 0; 71 | } 72 | int flow(int s, int t){ 73 | int max_flow=0; 74 | while(true){ 75 | if(bfs(s, t)) 76 | break; 77 | fill(idx.begin(), idx.end(), 0); 78 | while(true){ 79 | int flow=dfs(s, t, inf); 80 | if(flow==0) 81 | break; 82 | max_flow+=flow; 83 | } 84 | } 85 | return max_flow; 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /Graph/Hk.cpp: -------------------------------------------------------------------------------- 1 | class Hk{ 2 | public: 3 | int n; 4 | vector b; 5 | vector level; 6 | vector trip; 7 | vector > &adj; 8 | vector idx; 9 | Hk(vector > &adj):adj(adj){ 10 | n=adj.size(); 11 | b=vector(n); 12 | level=vector(n); 13 | trip=vector(n); 14 | idx=vector(n); 15 | } 16 | void bfs(){ 17 | fill(level.begin(), level.end(), -1); 18 | queue q; 19 | for(int i=0;icost; 17 | return cost; 18 | } 19 | void push(int amt) { 20 | flow += amt; 21 | dual->flow -= amt; 22 | } 23 | }; 24 | vector > adj; 25 | MCMF(int n) :V(n), totalFlow(0), totalCost(0), adj(n) {} 26 | ~MCMF() { 27 | for (int i = 0; i < V; i++) 28 | for (int j = 0; j < adj[i].size(); j++) 29 | delete adj[i][j]; 30 | } 31 | void setEdge(int u, int v, int uvCapacity, int uvCost) { 32 | Edge* uv = new Edge(v, uvCapacity, uvCost); 33 | Edge* vu = new Edge(u, 0, 0); 34 | uv->dual = vu; 35 | vu->dual = uv; 36 | adj[u].push_back(uv); 37 | adj[v].push_back(vu); 38 | } 39 | int improve(int s, int t) { 40 | while (true) { 41 | vector dist(V, INF), par(V, -1), edgeNo(V, -1), capa(V, -1); 42 | par[s] = s; 43 | dist[s] = 0; 44 | capa[s] = INF; 45 | queue q; 46 | q.push(s); 47 | while (!q.empty()) { 48 | int now = q.front(); 49 | q.pop(); 50 | for (int i = 0; i < adj[now].size(); i++) { 51 | Edge* e = adj[now][i]; 52 | if (e->residual() <= 0) 53 | continue; 54 | int thereCost = dist[now] + e->getCost(); 55 | if (dist[e->target] > thereCost) { 56 | dist[e->target] = thereCost; 57 | q.push(e->target); 58 | par[e->target] = now; 59 | edgeNo[e->target] = i; 60 | capa[e->target] = min(capa[now], e->residual()); 61 | } 62 | } 63 | } 64 | if (dist[t] == INF) 65 | break; 66 | int here = t, amt = capa[t]; 67 | while (here != s) { 68 | int there = par[here]; 69 | adj[there][edgeNo[here]]->push(amt); 70 | here = there; 71 | } 72 | totalFlow += amt; 73 | totalCost += dist[t] * amt; 74 | } 75 | return totalCost; 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /Graph/readme.txt: -------------------------------------------------------------------------------- 1 | 디닉 더빠른거 2 | -------------------------------------------------------------------------------- /Graph/scc.cpp: -------------------------------------------------------------------------------- 1 | struct Scc{ 2 | vector> adj; 3 | vector scc; 4 | vector discoverd; 5 | stack st; 6 | int vertex_count; 7 | int scc_count; 8 | int v; 9 | Scc(const vector> &adj):adj(adj){ 10 | v=adj.size()-1; 11 | scc=vector(v+1, -1); 12 | discoverd=vector(v+1, -1); 13 | vertex_count=0; 14 | scc_count=0; 15 | } 16 | int dfs(int now){ 17 | int ret=discoverd[now]=vertex_count++; 18 | st.push(now); 19 | for(int i=0;i make_scc(){ 39 | for(int i=1;i<=v;i++) 40 | if(discoverd[i]==-1) 41 | dfs(i); 42 | return scc; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /Math/extended_euclidean.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baactree/Algorithm/4a9a8ddb5e4b7da6f66b5f8dfb5a97f5e494e068/Math/extended_euclidean.cpp -------------------------------------------------------------------------------- /Math/fft.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baactree/Algorithm/4a9a8ddb5e4b7da6f66b5f8dfb5a97f5e494e068/Math/fft.cpp -------------------------------------------------------------------------------- /Math/ntt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef long long ll; 4 | namespace ntt{ 5 | #define sz(v) ((int)(v).size()) 6 | #define all(v) (v).begin(),(v).end() 7 | // + int *ll 8 | const int A = 45, B = 24, P = A << B | 1, R = 11; 9 | // + ll *llu 10 | //const ll A=3, B=30, P = A << B | 1, R = 5; 11 | 12 | inline int Pow(int x, int y) { 13 | int r = 1; 14 | while (y) { 15 | if (y & 1) r = (long long)r * x % P; 16 | x = (long long)x * x % P; 17 | y >>= 1; 18 | } 19 | return r; 20 | } 21 | void fft(vector &a, bool f) { 22 | int n=sz(a); 23 | for (int i=1,j=0;i> 1; 25 | for (;j>=bit;bit>>=1) j -= bit; 26 | j += bit; 27 | if (i < j) swap(a[i],a[j]); 28 | } 29 | for (int i = 1; i < n; i <<= 1) { 30 | int x = Pow(f ? Pow(R, P - 2) : R, P / i >> 1); 31 | for (int j = 0; j < n; j += i << 1) { 32 | int y = 1; 33 | for (int k = 0; k < i; k++) { 34 | int z = (long long)a[i | j | k] * y % P; 35 | a[i | j | k] = a[j | k] - z; 36 | if (a[i | j | k] < 0) a[i | j | k] += P; 37 | a[j | k] += z; 38 | if (a[j | k] >= P) a[j | k] -= P; 39 | y = (long long)y * x % P; 40 | } 41 | } 42 | } 43 | if (f) { 44 | int r=Pow(n,P-2); 45 | for (int i = 0; i < n; i++) a[i] = (long long)a[i] * r % P; 46 | } 47 | } 48 | 49 | void multiply(const vector &a,const vector &b,vector &res) 50 | { 51 | vector fa(all(a)), fb(all(b)); 52 | int n = 1; 53 | while (n < max(sz(a),sz(b))) n <<= 1; 54 | n*=2; 55 | fa.resize(n); fb.resize(n); 56 | fft(fa,false); fft(fb,false); 57 | for (int i=0;i 12 | using namespace std; 13 | typedef long long ll; 14 | int n, m, k; 15 | ll arr[1000000]; 16 | ll sq[1500]; 17 | int sz; 18 | ll query(int l, int r){ 19 | int lidx=l/sz; 20 | int ridx=r/sz; 21 | ll ret=0; 22 | if(lidx==ridx){ 23 | for(int i=l;i<=r;i++) 24 | ret+=arr[i]; 25 | return ret; 26 | } 27 | for(int i=lidx+1;i 2 | 3 | template 4 | struct map{ 5 | struct node{ 6 | node *l, *r, *p; 7 | K key; 8 | T val; 9 | }; 10 | node *root; 11 | map():root(0){} 12 | ~map(){ 13 | while (root) 14 | erase(root->key); 15 | } 16 | void rotate(node *x){ 17 | node *p = x->p; 18 | node *b; 19 | if (x == p->l){ 20 | p->l = b = x->r; 21 | x->r = p; 22 | } 23 | else{ 24 | p->r = b = x->l; 25 | x->l = p; 26 | } 27 | x->p = p->p; 28 | p->p = x; 29 | if (b) b->p = p; 30 | (x->p ? p == x->p->l ? x->p->l : x->p->r : root) = x; 31 | } 32 | void splay(node *x){ 33 | while (x->p){ 34 | node *p = x->p; 35 | node *g = p->p; 36 | if (g) rotate((x == p->l) == (p==g->l) ? p : x); 37 | rotate(x); 38 | } 39 | } 40 | void insert(K key,T val){ 41 | node *p = root, **pp; 42 | if (!p){ 43 | node *x = new node; 44 | root = x; 45 | x->l = x->r = x->p = 0; 46 | x->key = key; 47 | x->val = val; 48 | return; 49 | } 50 | while (true){ 51 | if (key == p->key) return; 52 | if (key < p->key){ 53 | if (!p->l){ 54 | pp = &p->l; 55 | break; 56 | } 57 | p = p->l; 58 | }else{ 59 | if (!p->r){ 60 | pp = &p->r; 61 | break; 62 | } 63 | p = p->r; 64 | } 65 | } 66 | node *x = new node; 67 | *pp = x; 68 | x->l = x->r = 0; 69 | x->p = p; 70 | x->key = key; 71 | x->val = val; 72 | splay(x); 73 | } 74 | bool find(K key){ 75 | node *p = root; 76 | if (!p) 77 | return false; 78 | while (p){ 79 | if (key == p->key)break; 80 | if (key < p->key){ 81 | if (!p->l)break; 82 | p = p->l; 83 | } 84 | else{ 85 | if (!p->r)break; 86 | p = p->r; 87 | } 88 | } 89 | splay(p); 90 | return key == p->key; 91 | } 92 | void erase(K key){ 93 | if (!find(key))return; 94 | node *p = root; 95 | if (p->l){ 96 | if (p->r){ 97 | root = p->l; 98 | root->p = 0; 99 | node *x = root; 100 | while (x->r)x = x->r; 101 | x->r = p->r; 102 | p->r->p = x; 103 | delete p; 104 | return; 105 | } 106 | root = p->l; 107 | root->p = 0; 108 | delete p; 109 | return; 110 | } 111 | if (p->r){ 112 | root = p->r; 113 | root->p = 0; 114 | delete p; 115 | return; 116 | } 117 | root = 0; 118 | } 119 | void clear(){ 120 | while (root) 121 | erase(root->key); 122 | } 123 | int count(K key){ 124 | return find(key); 125 | } 126 | T& operator [](K key){ 127 | if (!find(key)) 128 | insert(key, T(0)); 129 | return root->val; 130 | } 131 | }; 132 | -------------------------------------------------------------------------------- /Stl/pq.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | template 4 | struct vector{ 5 | T *arr; 6 | int c, s; 7 | vector(){ 8 | arr=new T[4]; 9 | c=4; 10 | s=0; 11 | } 12 | vector(int n){ 13 | arr=new T[n]; 14 | c=n; 15 | s=n; 16 | } 17 | void resize(int n){ 18 | T *t=new T[n]; 19 | for(int i=0;i 40 | struct priority_queue{ 41 | vector tree; 42 | int s; 43 | priority_queue(){ 44 | tree.resize(1); 45 | s=0; 46 | } 47 | void push(T d){ 48 | tree.push_back(d); 49 | s++; 50 | int idx=s; 51 | while(idx>1){ 52 | if(tree[idx]>tree[idx/2]) 53 | swap(tree[idx], tree[idx/2]); 54 | else 55 | break; 56 | idx/=2; 57 | } 58 | } 59 | T top(){ 60 | return tree[1]; 61 | } 62 | bool empty(){ 63 | return s==0; 64 | } 65 | void pop(){ 66 | swap(tree[1], tree[s]); 67 | tree.pop_back(); 68 | int idx=1; 69 | s--; 70 | while(true){ 71 | int next=-1; 72 | int now=tree[idx]; 73 | if(idx*2<=s&&now pq; 92 | while(n--){ 93 | int x; 94 | scanf("%d", &x); 95 | if(x){ 96 | pq.push(x); 97 | } 98 | else{ 99 | if(pq.empty()) 100 | printf("0\n"); 101 | else{ 102 | printf("%d\n", pq.top()); 103 | pq.pop(); 104 | } 105 | } 106 | } 107 | return 0; 108 | 109 | } -------------------------------------------------------------------------------- /Stl/queue.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: queue.cpp 4 | // Created: 2017년 04월 06일 23시 22분 05초 5 | // Compiler: g++ -O2 -std=c++14 6 | // Author: baactree , bsj0206@naver.com 7 | // Company: Chonnam National University 8 | // 9 | // ===================================================================================== 10 | 11 | #include 12 | using namespace std; 13 | 14 | template 15 | class _queue { 16 | public: 17 | struct Node { 18 | T val; 19 | Node *next; 20 | Node() {} 21 | Node(T val) :val(val), next(0){} 22 | }; 23 | Node *head; 24 | Node *tail; 25 | int _size; 26 | _queue() { 27 | head = tail = 0; 28 | _size = 0; 29 | } 30 | void push(T val) { 31 | Node *temp = new Node(val); 32 | if (head == 0) 33 | head = tail = temp; 34 | else { 35 | tail->next = temp; 36 | tail = temp; 37 | } 38 | _size++; 39 | } 40 | void pop() { 41 | Node *temp = head; 42 | head = head->next; 43 | delete temp; 44 | _size--; 45 | } 46 | bool empty() const{ 47 | return _size == 0; 48 | } 49 | T front() const{ 50 | return head->val; 51 | } 52 | T back() const{ 53 | return tail->val; 54 | } 55 | int size() const{ 56 | return _size; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /Stl/readme.txt: -------------------------------------------------------------------------------- 1 | 우선순위큐 추가 - Done 2 | -------------------------------------------------------------------------------- /Stl/set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | template 5 | class _set { 6 | public: 7 | struct Node { 8 | T val; 9 | int size, priority; 10 | Node *left, *right; 11 | Node(T val):val(val),size(1),priority(rand()),left(0),right(0){} 12 | void setleft(Node *v) { 13 | left = v; 14 | size = 1; 15 | if (left != 0) 16 | size += left->size; 17 | if (right != 0) 18 | size += right->size; 19 | } 20 | void setright(Node *v) { 21 | right = v; 22 | size = 1; 23 | if (left != 0) 24 | size += left->size; 25 | if (right != 0) 26 | size += right->size; 27 | } 28 | }; 29 | 30 | Node *root; 31 | _set():root(0){} 32 | pair split(Node *root, T val) { 33 | if (root == 0) 34 | return{ 0,0 }; 35 | if (root->val < val) { 36 | pair ret = split(root->right, val); 37 | root->setright(ret.first); 38 | return{ root,ret.second }; 39 | } 40 | pair ret = split(root->left, val); 41 | root->setleft(ret.second); 42 | return{ ret.first,root }; 43 | } 44 | Node* insert(Node* root, Node *node) { 45 | if (root == 0) 46 | return node; 47 | if (node->priority > root->priority) { 48 | pair ret = split(root, node->val); 49 | node->setleft(ret.first); 50 | node->setright(ret.second); 51 | return node; 52 | } 53 | if (root->val < node->val) 54 | root->setright(insert(root->right, node)); 55 | else 56 | root->setleft(insert(root->left, node)); 57 | return root; 58 | } 59 | void insert(T val) { 60 | root = insert(root, new Node(val)); 61 | } 62 | Node* merge(Node *a, Node *b) { 63 | if (a == 0) 64 | return b; 65 | if (b == 0) 66 | return a; 67 | if (a->priority < b->priority) { 68 | if (b->val < a->val) { 69 | b->setright(merge(a, b->right)); 70 | return b; 71 | } 72 | b->setleft(merge(a, b->left)); 73 | return b; 74 | } 75 | if (a->val < b->val) { 76 | a->setright(merge(a->right, b)); 77 | return a; 78 | } 79 | a->setleft(merge(a->left, b)); 80 | return a; 81 | } 82 | Node *erase(Node *root, T val) { 83 | if (root == 0) 84 | return 0; 85 | if (root->val == val) { 86 | Node *ret = merge(root->left, root->right); 87 | delete root; 88 | return ret; 89 | } 90 | if (root->val < val) 91 | root->setright(erase(root->right, val)); 92 | else 93 | root->setleft(erase(root->left, val)); 94 | return root; 95 | } 96 | bool find(Node *root, T val) { 97 | if (root == 0) 98 | return false; 99 | if (root->val == val) 100 | return true; 101 | if (root->val < val) 102 | return find(root->right, val); 103 | return find(root->left, val); 104 | } 105 | bool find(T val) { 106 | return find(root, val); 107 | } 108 | int countLessThan(Node *root, T key) { 109 | if (root == NULL) 110 | return 0; 111 | if (root->key >= key) 112 | return countLessThan(root->left, key); 113 | int ls = (root->left ? root->left->size : 0); 114 | return ls + 1 + countLessThan(root->right, key); 115 | } 116 | }; 117 | -------------------------------------------------------------------------------- /Stl/sort.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: sort.cpp 4 | // Created: 2017년 03월 01일 01시 41분 31초 5 | // Compiler: g++ -O2 -std=c++14 6 | // Author: baactree , bsj0206@naver.com 7 | // Company: Chonnam National University 8 | // 9 | // ===================================================================================== 10 | 11 | #include 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | 17 | template 18 | void _swap(It &a, It &b){ 19 | It c(a);a=b;b=c; 20 | } 21 | template 22 | void _sort(It begin, It end, Comp comp){ 23 | if(begin==end) 24 | return; 25 | _swap(*begin, *((end-begin)/2+begin)); 26 | It pi = begin; 27 | It le = begin + 1; 28 | It ri = end - 1; 29 | while( le <= ri ) { 30 | while(le <= ri && !comp(*pi, *le)) 31 | le++; 32 | while(le <= ri && !comp(*ri, *pi)) 33 | ri--; 34 | if(le<=ri) 35 | _swap(*le, *ri); 36 | } 37 | _swap(*pi, *ri); 38 | _sort(begin, ri, comp); 39 | _sort(ri + 1, end, comp); 40 | } 41 | 42 | template 43 | struct _pair{ 44 | A first; 45 | B second; 46 | _pair(A a, B b):first(a), second(b){} 47 | _pair(){} 48 | }; 49 | 50 | bool cmp(const _pair& a, const _pair& b){ 51 | if(a.first==b.first) 52 | return a.second > arr; 59 | int n; 60 | scanf("%d", &n); 61 | for(int i=0;i 12 | using namespace std; 13 | 14 | template 15 | class _stack { 16 | public: 17 | struct Node { 18 | T val; 19 | Node *next; 20 | Node() {} 21 | Node(T val) :val(val), next(0){} 22 | }; 23 | Node *head; 24 | int _size; 25 | _stack() { 26 | head = 0; 27 | _size = 0; 28 | } 29 | void push(T val) { 30 | Node *temp = new Node(val); 31 | if (head == 0) 32 | head = temp; 33 | else { 34 | temp->next = head; 35 | head = temp; 36 | } 37 | _size++; 38 | } 39 | void pop() { 40 | Node *temp = head; 41 | head = head->next; 42 | delete temp; 43 | _size--; 44 | } 45 | bool empty() const{ 46 | return _size == 0; 47 | } 48 | T top() const{ 49 | return head->val; 50 | } 51 | int size() const{ 52 | return _size; 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /Stl/vector.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: vector.cpp 4 | // Created: 2017년 04월 06일 23시 19분 16초 5 | // Compiler: g++ -O2 -std=c++14 6 | // Author: baactree , bsj0206@naver.com 7 | // Company: Chonnam National University 8 | // 9 | // ===================================================================================== 10 | 11 | #include 12 | using namespace std; 13 | 14 | template 15 | class _vector { 16 | public: 17 | int _size; 18 | int capacity; 19 | T *arr; 20 | _vector() { 21 | _size = 0; 22 | capacity = 32; 23 | arr = new T[capacity]; 24 | } 25 | _vector(int k) { 26 | _size = k; 27 | capacity = k; 28 | arr = new T[capacity]; 29 | } 30 | ~_vector(){ 31 | delete[] arr; 32 | } 33 | void clear(){ 34 | delete[] arr; 35 | _size = 0; 36 | capacity = 32; 37 | arr = new T[capacity]; 38 | } 39 | void resize(int k) { 40 | T *temp; 41 | temp = new T[k]; 42 | for (int i = 0; i < _size; i++) 43 | temp[i] = arr[i]; 44 | delete[] arr; 45 | arr = temp; 46 | _size=capacity=k; 47 | } 48 | int size() const{ 49 | return _size; 50 | } 51 | T* begin() const{ 52 | return &arr[0]; 53 | } 54 | T* end() const{ 55 | return &arr[0] + _size; 56 | } 57 | void push_back(T val) { 58 | if (_size == capacity) { 59 | resize(_size * 2); 60 | _size /=2; 61 | } 62 | arr[_size++] = val; 63 | } 64 | void pop_back() { 65 | _size--; 66 | } 67 | T& operator [](int idx) { 68 | return arr[idx]; 69 | } 70 | T operator [](int idx)const{ 71 | return arr[idx]; 72 | } 73 | }; 74 | -------------------------------------------------------------------------------- /String/kmp.cpp: -------------------------------------------------------------------------------- 1 | class Kmp { 2 | public: 3 | vector get_pi(const string& N) { 4 | int m = N.length(); 5 | vector pi(m, 0); 6 | int begin = 1, matched = 0; 7 | while (begin+matched < m) { 8 | if (N[begin + matched] == N[matched]) { 9 | matched++; 10 | pi[begin + matched - 1] = matched; 11 | } 12 | else { 13 | if (matched == 0) { 14 | begin++; 15 | } 16 | else { 17 | begin = begin + matched - pi[matched - 1]; 18 | matched = pi[matched - 1]; 19 | } 20 | } 21 | } 22 | return pi; 23 | } 24 | vector get_kmp(const string& H,const string& N) { 25 | int n = H.length(); 26 | int m = N.length(); 27 | vector ret; 28 | vector pi = get_pi(N); 29 | int begin = 0, matched = 0; 30 | while (begin <= n - m) { 31 | if (matched < m&&H[begin + matched] == N[matched]) { 32 | matched++; 33 | if (matched == m) 34 | ret.push_back(begin); 35 | } 36 | else { 37 | if (matched == 0) 38 | begin++; 39 | else { 40 | begin = begin + matched - pi[matched - 1]; 41 | matched = pi[matched - 1]; 42 | } 43 | } 44 | } 45 | return ret; 46 | } 47 | 48 | }; 49 | -------------------------------------------------------------------------------- /String/lcparray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define MAXN 500005 5 | 6 | int N,SA[MAXN],lcp[MAXN]; 7 | char S[MAXN]; 8 | 9 | void LCP() 10 | { 11 | int i,j,k=0; 12 | vector rank(N+1,0); 13 | for (i=1;i<=N;i++) rank[SA[i]] = i; 14 | for (i=1;i<=N;lcp[rank[i++]]=k) 15 | for (k?k--:0,j=SA[rank[i]-1];S[i+k]==S[j+k];k++); 16 | } 17 | 18 | 19 | //출처: http://blog.myungwoo.kr/57 [PS 이야기] 20 | -------------------------------------------------------------------------------- /String/readme.txt: -------------------------------------------------------------------------------- 1 | 매나처 추가 2 | z-알고리즘 추가 3 | -------------------------------------------------------------------------------- /String/suffixarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define MAXN 500005 5 | 6 | int N,SA[MAXN]; 7 | char S[MAXN]; 8 | 9 | void SuffixArray() 10 | { 11 | int i,j,k; 12 | int m = 26; // 처음 알파벳 개수 13 | vector cnt(max(N,m)+1,0),x(N+1,0),y(N+1,0); 14 | for (i=1;i<=N;i++) cnt[x[i] = S[i]-'a'+1]++; 15 | for (i=1;i<=m;i++) cnt[i] += cnt[i-1]; 16 | for (i=N;i;i--) SA[cnt[x[i]]--] = i; 17 | for (int len=1,p=1;p len) y[++p] = SA[i]-len; 20 | for (i=0;i<=m;i++) cnt[i] = 0; 21 | for (i=1;i<=N;i++) cnt[x[y[i]]]++; 22 | for (i=1;i<=m;i++) cnt[i] += cnt[i-1]; 23 | for (i=N;i;i--) SA[cnt[x[y[i]]]--] = y[i]; 24 | swap(x,y); p = 1; x[SA[1]] = 1; 25 | for (i=1;i 12 | using namespace std; 13 | vector > mat; 14 | int n, m; 15 | struct Indextree{ 16 | vector > tree; 17 | int n; 18 | Indextree(const vector > &mat){ 19 | n=1; 20 | while(n >(n, vector(n, 0)); 24 | init(mat); 25 | } 26 | void init(const vector > &mat){ 27 | for(int i=0;i1){ 32 | idx/=2; 33 | tree[i+n/2][idx]=tree[i+n/2][idx*2]+tree[i+n/2][idx*2+1]; 34 | } 35 | } 36 | for(int j=1;j1){ 39 | idx/=2; 40 | tree[idx][j]=tree[idx*2][j]+tree[idx*2+1][j]; 41 | } 42 | } 43 | } 44 | } 45 | int query(int x1, int y1, int x2, int y2){ 46 | x1+=n/2; 47 | x2+=n/2; 48 | int ret=0; 49 | while(x1<=x2){ 50 | if(x1&1){ 51 | int a=y1+n/2; 52 | int b=y2+n/2; 53 | while(a<=b){ 54 | if(a&1){ 55 | ret+=tree[x1][a]; 56 | a++; 57 | } 58 | if(!(b&1)){ 59 | ret+=tree[x1][b]; 60 | b--; 61 | } 62 | a/=2; 63 | b/=2; 64 | } 65 | x1++; 66 | } 67 | if(!(x2&1)){ 68 | int a=y1+n/2; 69 | int b=y2+n/2; 70 | while(a<=b){ 71 | if(a&1){ 72 | ret+=tree[x2][a]; 73 | a++; 74 | } 75 | if(!(b&1)){ 76 | ret+=tree[x2][b]; 77 | b--; 78 | } 79 | a/=2; 80 | b/=2; 81 | } 82 | x2--; 83 | } 84 | x1/=2; 85 | x2/=2; 86 | } 87 | return ret; 88 | } 89 | void update(int x, int y, int val){ 90 | x+=n/2; 91 | y+=n/2; 92 | tree[x][y]=val; 93 | int tx=x; 94 | while(tx>1){ 95 | int ty=y; 96 | while(ty>1){ 97 | tree[tx/2][ty]=tree[tx/2*2][ty]+tree[tx/2*2+1][ty]; 98 | ty/=2; 99 | tree[tx][ty]=tree[tx][ty*2]+tree[tx][ty*2+1]; 100 | tree[tx/2][ty]=tree[tx/2*2][ty]+tree[tx/2*2+1][ty]; 101 | } 102 | tx/=2; 103 | } 104 | } 105 | }; 106 | int main(){ 107 | scanf("%d%d", &n, &m); 108 | mat=vector >(n, vector(n, 0)); 109 | for(int i=0;i 12 | using namespace std; 13 | struct Segmenttree{ 14 | vector > tree; 15 | int n; 16 | Segmenttree(const vector > &mat){ 17 | n=1; 18 | while(n >(n, vector(n, 0)); 22 | init(mat, 0, mat.size()-1, 1, 0, mat.size()-1, 1); 23 | } 24 | int init(const vector > &mat, int xle, int xri, int xnode, int yle, int yri, int ynode){ 25 | if(xle==xri){ 26 | if(yle==yri) 27 | return tree[xnode][ynode]=mat[xle][yle]; 28 | int mid=(yle+yri)/2; 29 | int left_ret=init(mat, xle, xri, xnode, yle, mid, ynode*2); 30 | int right_ret=init(mat, xle, xri, xnode, mid+1, yri, ynode*2+1); 31 | return tree[xnode][ynode]=left_ret+right_ret; 32 | } 33 | int mid=(xle+xri)/2; 34 | init(mat, xle, mid, xnode*2, yle, yri, ynode); 35 | init(mat, mid+1, xri, xnode*2+1, yle, yri, ynode); 36 | for(int i=1;ixri||x2yri||y21){ 74 | tree[xnode][ty]=tree[xnode*2][ty]+tree[xnode*2+1][ty]; 75 | ty/=2; 76 | } 77 | return tree[xnode][ynode]=tree[xnode*2][ynode]+tree[xnode*2+1][ynode]; 78 | } 79 | }; 80 | vector > mat; 81 | int n, m; 82 | int main(){ 83 | scanf("%d%d", &n, &m); 84 | mat=vector >(n, vector(n, 0)); 85 | for(int i=0;i 12 | using namespace std; 13 | template 14 | struct Indextree{ 15 | vector tree; 16 | int n; 17 | Indextree(const vector &arr){ 18 | n=1; 19 | while(n(n*2, 0); 22 | init(arr); 23 | } 24 | void init(const vector &arr){ 25 | for(int i=0;i>= 1; 30 | } 31 | } 32 | } 33 | T query(int a, int b){ 34 | T ret=0; 35 | a+=n; 36 | b+=n; 37 | while(a<=b){ 38 | if(a&1) 39 | ret+=tree[a++]; 40 | if(!(b&1)) 41 | ret+=tree[b--]; 42 | a >>= 1; 43 | b >>= 1; 44 | } 45 | return ret; 46 | } 47 | void update(int a, T b){ 48 | a+=n; 49 | while(a){ 50 | tree[a] += b; 51 | a >>= 1; 52 | } 53 | } 54 | }; 55 | int main(){ 56 | int n, m, k; 57 | scanf("%d%d%d", &n, &m, &k); 58 | vector arr(n); 59 | for(int i=0;i idtree(arr); 62 | for(int i=0;i 12 | using namespace std; 13 | template 14 | struct Indextree{ 15 | int n; 16 | vector > tree; 17 | Indextree(const vector& arr){ 18 | n=1; 19 | while(n > (n, {0, 0}); 23 | init(arr); 24 | } 25 | void init(const vector& arr){ 26 | for(int i=0;i arr(n); 97 | for(int i=0;i idtree(arr); 100 | for(int i=0;i pii; 9 | typedef vector > Edge; 10 | typedef unsigned long long llu; 11 | typedef long long ll; 12 | typedef priority_queue Pq; 13 | typedef vector::iterator It; 14 | #define INF 0x3f3f3f3f 15 | #define UINF 0xffffffffu 16 | #define LINF 0x3f3f3f3f3f3f3f3fll 17 | #define MOD 1000000007 18 | #define EOD 1e-9 19 | #define all(x) x.begin(),x.end() 20 | const double PI = acos(0.0)*2.0; 21 | ///////////////////////////////////////////////////// 22 | struct Node { 23 | ll value, update; 24 | Node(){} 25 | Node(ll value,ll update):value(value),update(update){} 26 | Node operator + (const Node& rhs)const { 27 | return{ value + rhs.value,update + rhs.update }; 28 | } 29 | }; 30 | struct Tree { 31 | int n; 32 | vector tree; 33 | Tree(int n) :n(n) { 34 | tree.resize(n * 4); 35 | } 36 | Node init(const vector &arr, int left, int right, int node) { 37 | if (left == right) 38 | return tree[node] = { arr[left],0 }; 39 | int mid = (left + right) / 2; 40 | return tree[node] = init(arr, left, mid, node * 2) + init(arr, mid + 1, right, node * 2 + 1); 41 | } 42 | void init(const vector &arr) { 43 | init(arr, 0, n - 1, 1); 44 | } 45 | void update(int left, int right, int value, int nodeleft, int noderight, int node) { 46 | if (left > noderight || right < nodeleft) 47 | return; 48 | if (left <= nodeleft&&noderight <= right) { 49 | tree[node].update += value; 50 | return; 51 | } 52 | int mid = (nodeleft + noderight) / 2; 53 | update(left, right, value, nodeleft, mid, node * 2); 54 | update(left, right, value, mid + 1, noderight, node * 2 + 1); 55 | tree[node].value = tree[node * 2].value + tree[node * 2 + 1].value + tree[node * 2].update*(mid - nodeleft + 1) + tree[node * 2 + 1].update*(noderight - mid); 56 | } 57 | void update(int left, int right, int value) { 58 | update(left, right, value, 0, n - 1, 1); 59 | } 60 | ll query(int left, int right, int nodeleft, int noderight, int node,int update) { 61 | tree[node].update += update; 62 | if (left > noderight || right < nodeleft) 63 | return 0; 64 | if (left <= nodeleft&&noderight <= right) 65 | return tree[node].value + tree[node].update*(noderight - nodeleft + 1); 66 | int mid = (nodeleft + noderight) / 2; 67 | int nextupdate = tree[node].update; 68 | tree[node].update = 0; 69 | ll leftret = query(left, right, nodeleft, mid, node * 2, nextupdate); 70 | ll rightret = query(left, right, mid + 1, noderight, node * 2 + 1, nextupdate); 71 | tree[node].value = tree[node * 2].value + tree[node * 2 + 1].value + tree[node * 2].update*(mid - nodeleft + 1) + tree[node * 2 + 1].update*(noderight - mid); 72 | return leftret + rightret; 73 | } 74 | ll query(int left, int right) { 75 | return query(left, right, 0, n - 1, 1, 0); 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /Tree/Treap.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: Treap.cpp 4 | // Created: 2017년 03월 23일 15시 30분 56초 5 | // Compiler: g++ -O2 -std=c++14 6 | // Author: baactree , bsj0206@naver.com 7 | // Company: Chonnam National University 8 | // 9 | // ===================================================================================== 10 | 11 | #include 12 | using namespace std; 13 | typedef long long ll; 14 | template 15 | struct Treap{ 16 | struct Node { 17 | KeyType key; 18 | int priority, size; 19 | Node *left, *right; 20 | Node(const KeyType key):key(key),priority(rand()),size(1),left(NULL),right(NULL){} 21 | void setLeft(Node *newLeft) { 22 | left = newLeft; 23 | calcSize(); 24 | } 25 | void setRight(Node *newRight) { 26 | right = newRight; 27 | calcSize(); 28 | } 29 | void calcSize() { 30 | size = 1; 31 | if (left) 32 | size += left->size; 33 | if (right) 34 | size += right->size; 35 | } 36 | }; 37 | Node *root; 38 | Treap(){ 39 | root=0; 40 | } 41 | Node* make_Node(KeyType key){ 42 | Node* ret=new Node(key); 43 | return ret; 44 | } 45 | typedef pair NodePair; 46 | NodePair split(Node *root, KeyType key) { 47 | if (root == NULL)return NodePair(NULL, NULL); 48 | if (root->key < key) { 49 | NodePair rs = split(root->right, key); 50 | root->setRight(rs.first); 51 | return NodePair(root, rs.second); 52 | } 53 | NodePair ls = split(root->left, key); 54 | root->setLeft(ls.second); 55 | return NodePair(ls.first, root); 56 | } 57 | Node* insert(Node *root, Node *node) { 58 | if (root == NULL) 59 | return node; 60 | if (root->priority < node->priority) { 61 | NodePair splitted = split(root, node->key); 62 | node->setLeft(splitted.first); 63 | node->setRight(splitted.second); 64 | return node; 65 | } 66 | else if (root->key < node->key) { 67 | root->setRight(insert(root->right, node)); 68 | } 69 | else 70 | root->setLeft(insert(root->left, node)); 71 | return root; 72 | } 73 | Node* merge(Node *a, Node *b) { 74 | if (a == NULL) 75 | return b; 76 | if (b == NULL) 77 | return a; 78 | if (a->priority < b->priority) { 79 | b->setLeft(merge(a, b->left)); 80 | return b; 81 | } 82 | a->setRight(merge(a->right, b)); 83 | return a; 84 | } 85 | Node* erase(Node *root, KeyType key) { 86 | if (root == NULL) 87 | return root; 88 | if (root->key == key) { 89 | Node *ret = merge(root->left, root->right); 90 | delete root; 91 | return ret; 92 | } 93 | if (root->key < key) 94 | root->setRight(erase(root->right, key)); 95 | else 96 | root->setLeft(erase(root->left, key)); 97 | return root; 98 | } 99 | int countLessThan(Node* root, KeyType key){ 100 | if(root==NULL)return 0; 101 | if(root->key>=key) 102 | return countLessThan(root->left, key); 103 | int ls=(root->left?root->left->size:0); 104 | return ls+1+countLessThan(root->right, key); 105 | } 106 | }; 107 | 108 | int a[200001]; 109 | Treap tree[200001]; 110 | int n, q; 111 | void update(int idx, int val){ 112 | while(idx<=n){ 113 | tree[idx].root=tree[idx].insert(tree[idx].root, tree[idx].make_Node(val)); 114 | idx+=idx&(-idx); 115 | } 116 | } 117 | void erase(int idx, int val){ 118 | while(idx<=n){ 119 | tree[idx].root=tree[idx].erase(tree[idx].root, val); 120 | idx+=idx&(-idx); 121 | } 122 | } 123 | ll query(int idx, int val){ 124 | ll ret=0; 125 | while(idx>0){ 126 | ret+=tree[idx].countLessThan(tree[idx].root, val); 127 | idx-=idx&(-idx); 128 | } 129 | return ret; 130 | } 131 | int main(){ 132 | scanf("%d%d", &n, &q); 133 | for(int i=1;i<=n;i++){ 134 | a[i]=i; 135 | update(i, i); 136 | } 137 | long long ans=0; 138 | for(int i=0;ic) 142 | swap(b, c); 143 | if(b==c){ 144 | printf("%lld\n", ans); 145 | continue; 146 | } 147 | int now, lcnt, rcnt; 148 | 149 | now=query(b, a[b]);//b보다 왼쪽으로 a[b]보다 작은 값의 수 150 | lcnt=b-1-now;//b보다 왼쪽으로 a[b]보다 큰 값의 수 151 | rcnt=a[b]-1-now;//b보다 오른쪽으로 a[b]보다 작은 값의 수 152 | ans-=(lcnt+rcnt); 153 | erase(b, a[b]); 154 | 155 | now=query(c, a[c]); 156 | lcnt=c-2-now; 157 | rcnt=a[c]-1-now-(a[b] 2 | using namespace std; 3 | typedef long long ll; 4 | template 5 | struct Splay_tree{ 6 | struct node{ 7 | node *l,*r,*p; 8 | T key; 9 | int cnt; 10 | ll sum,value,lazy; 11 | bool inv; 12 | }; 13 | node *tree; 14 | Splay_tree(){ 15 | tree=NULL; 16 | } 17 | ~Splay_tree(){ 18 | while(tree) 19 | erase(tree->key); 20 | } 21 | void push(node *x){ 22 | x->value+=x->lazy; 23 | if(x->l){ 24 | x->l->lazy+=x->lazy; 25 | x->l->sum+=x->l->cnt*x->lazy; 26 | } 27 | if(x->r){ 28 | x->r->lazy+=x->lazy; 29 | x->r->sum+=x->r->cnt*x->lazy; 30 | } 31 | x->lazy=0; 32 | // reverse 33 | /* 34 | if(!x->inv) 35 | return; 36 | node *t=x->l; 37 | x->l=x->r; 38 | x->r=t; 39 | x->inv=false; 40 | if(x->l) 41 | x->l->inv=!x->l->inv; 42 | if(x->r) 43 | x->r->inv=!=x->r->inv; 44 | */ 45 | } 46 | void update(node *x){ 47 | x->cnt=1; 48 | x->sum=x->value; 49 | if(x->l){ 50 | x->cnt+=x->l->cnt; 51 | x->sum+=x->l->sum; 52 | } 53 | if(x->r){ 54 | x->cnt+=x->r->cnt; 55 | x->sum+=x->r->sum; 56 | } 57 | } 58 | void rotate(node *x){ 59 | node *p=x->p; 60 | node *b; 61 | if(x==p->l){ 62 | p->l=b=x->r; 63 | x->r=p; 64 | } 65 | else{ 66 | p->r=b=x->l; 67 | x->l=p; 68 | } 69 | x->p=p->p; 70 | p->p=x; 71 | if(b) b->p=p; 72 | (x->p?p==x->p->l?x->p->l:x->p->r:tree)=x; 73 | update(p); 74 | update(x); 75 | } 76 | void splay(node *x){ 77 | while(x->p){ 78 | node *p=x->p; 79 | node *g=p->p; 80 | if(g) rotate((x==p->l)==(p==g->l)?p:x); 81 | rotate(x); 82 | } 83 | } 84 | void insert(T key){ 85 | node *p=tree,**pp; 86 | if(!p){ 87 | node *x=new node; 88 | tree=x; 89 | x->l=x->r=x->p=NULL; 90 | x->key=key; 91 | return; 92 | } 93 | while(1){ 94 | if(key==p->key) 95 | return; 96 | if(keykey){ 97 | if(!p->l){ 98 | pp=&p->l; 99 | break; 100 | } 101 | p=p->l; 102 | } 103 | else{ 104 | if(!p->r){ 105 | pp=&p->r; 106 | break; 107 | } 108 | p=p->r; 109 | } 110 | } 111 | node *x=new node; 112 | *pp=x; 113 | x->l=x->r=NULL; 114 | x->p=p; 115 | x->key=key; 116 | splay(x); 117 | } 118 | bool find(T key){ 119 | node *p=tree; 120 | if(!p) 121 | return false; 122 | while(p){ 123 | if(key==p->key) 124 | break; 125 | if(keykey){ 126 | if(!p->l) 127 | break; 128 | p=p->l; 129 | } 130 | else{ 131 | if(!p->r) 132 | break; 133 | p=p->r; 134 | } 135 | } 136 | splay(p); 137 | return key==p->key; 138 | } 139 | void erase(T key){ 140 | if(!find(key)) 141 | return; 142 | node *p=tree; 143 | if(p->l){ 144 | if(p->r){ 145 | tree=p->l; 146 | tree->p=NULL; 147 | node *x=tree; 148 | while(x->r) 149 | x=x->r; 150 | x->r=p->r; 151 | p->r->p=x; 152 | splay(x); 153 | delete p; 154 | return; 155 | } 156 | tree=p->l; 157 | tree->p=NULL; 158 | delete p; 159 | return; 160 | } 161 | if(p->r){ 162 | tree=p->r; 163 | tree->p=NULL; 164 | delete p; 165 | return; 166 | } 167 | tree=NULL; 168 | } 169 | //0-based 170 | void find_kth(int k){ 171 | node *x=tree; 172 | push(x); 173 | while(true){ 174 | while(x->l&&x->l->cnt>k){ 175 | x=x->l; 176 | push(x); 177 | } 178 | if(x->l) 179 | k-=x->l->cnt; 180 | if(!k--) 181 | break; 182 | x=x->r; 183 | push(x); 184 | } 185 | splay(x); 186 | } 187 | void init(int n){ 188 | n+=2; 189 | node *x; 190 | tree=x=new node; 191 | x->l=x->r=x->p=NULL; 192 | x->cnt=n; 193 | x->sum=x->value=x->lazy=0; 194 | for(int i=1;ir=new node; 196 | x->r->p=x; 197 | x=x->r; 198 | x->l=x->r=NULL; 199 | x->cnt=n-i; 200 | x->sum=x->value=x->lazy=0; 201 | } 202 | } 203 | //1-based 204 | void interval(int l,int r){ 205 | find_kth(l-1); 206 | node *x=tree; 207 | tree=x->r; 208 | tree->p=NULL; 209 | find_kth(r-l+1); 210 | x->r=tree; 211 | tree->p=x; 212 | tree=x; 213 | } 214 | void add(int l, int r, ll val){ 215 | interval(l,r); 216 | node *x=tree->r->l; 217 | x->sum+=x->cnt*val; 218 | x->lazy+=val; 219 | } 220 | ll sum(int l,int r){ 221 | interval(l,r); 222 | return tree->r->l->sum; 223 | } 224 | void reverse(int l,int r){ 225 | interval(l,r); 226 | node *x=tree->r->l; 227 | x->inv=!x->inv; 228 | } 229 | }; 230 | int n,m,k; 231 | ll arr[1000005]; 232 | int main(){ 233 | scanf("%d%d%d",&n,&m,&k); 234 | Splay_tree sptree; 235 | sptree.init(n); 236 | for(int i=1;i<=n;i++){ 237 | scanf("%lld",&arr[i]); 238 | sptree.add(i,i,arr[i]); 239 | } 240 | for(int i=0;i