正解大概是splay吧,不想写splay用块链过了
旋转、赋值打标记就好了
求MAX-SUM要维护一下每块的 和、最大子段和、前缀和最大最小值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define SQRTN 750
#define MAXBL 1000
#define MAXN 500003
#define INF (2000 * SQRTN * 2)
typedef struct Block *PBlock;
struct Block
{
int a[SQRTN << 4];
int size;
int hvsm, sm;
int rev;
int sum;
int msum, mmax, mmin, rmax, rmin;
} pool[MAXBL];
PBlock blst[MAXBL]; /*block stack*/
int tblst; /*top block stack*/
typedef struct List *PList;
struct List
{
PBlock a;
PList last, next;
};
void calc(PBlock p)
{
p->mmin = INF;
p->msum = p->mmax = -INF;
int smin = 0, j;
p->sum = 0;
for (j = 0; j < p->size; ++j)
{
p->sum += p->a[j];
if (p->mmin > p->sum)
p->mmin = p->sum;
if (p->mmax < p->sum)
p->mmax = p->sum;
if (p->sum - smin > p->msum)
p->msum = p->sum - smin;
if (p->sum < smin)
smin = p->sum;
}
smin = 0;
p->sum = 0;
p->rmin = INF, p->rmax = -INF;
for (j = p->size - 1; j >= 0; --j)
{
p->sum += p->a[j];
if (p->rmin > p->sum)
p->rmin = p->sum;
if (p->rmax < p->sum)
p->rmax = p->sum;
if (p->sum < smin)
smin = p->sum;
}
}
void build(int *a, int n, PList *head, PList *tail)
{
int i;
*head = *tail = NULL;
for (i = 0; i < n;)
{
PList p = (PList)malloc(sizeof(struct List));
p->a = blst[--tblst];
p->a->size = (i + SQRTN < n ? SQRTN : n - i);
memcpy(p->a->a, a + i, sizeof(int) * p->a->size);
p->a->hvsm = p->a->rev = 0;
calc(p->a);
p->last = *tail;
p->next = NULL;
if (*head == NULL)
*head = p;
else
(*tail)->next = p;
*tail = p;
i += p->a->size;
}
}
void pushflag(PList x)
{
int i;
if (x->a->hvsm)
{
for (i = 0; i < x->a->size; ++i)
x->a->a[i] = x->a->sm;
x->a->hvsm = x->a->rev = 0;
}
if (x->a->rev)
{
x->a->rev = 0;
for (i = 0; i * 2 < x->a->size; ++i)
{
int t = x->a->a[i];
x->a->a[i] = x->a->a[x->a->size - i - 1];
x->a->a[x->a->size - i - 1] = t;
}
}
}
PList head, tail;
void split(PList x, int l)
{
pushflag(x);
PList p = (PList)malloc(sizeof(struct List));
p->a = blst[--tblst];
p->a->size = x->a->size - l;
p->a->hvsm = p->a->rev = 0;
memcpy(p->a->a, x->a->a + l, sizeof(int) * p->a->size);
p->last = x, p->next = x->next;
if (x->next)
x->next->last = p;
x->a->size = l;
x->next = p;
calc(p->a);
calc(x->a);
if (x == tail)
tail = p;
}
void merge(PList x)
{
pushflag(x);
PList p = x->next;
pushflag(p);
memcpy(x->a->a + x->a->size, p->a->a, sizeof(int) * p->a->size);
x->a->size += p->a->size;
x->next = p->next;
if (p->next)
p->next->last = x;
calc(x->a);
if (p == tail)
tail = x;
blst[tblst++] = p->a;
free(p);
}
PList findl(int num)
{
PList p;
for (p = head; num > p->a->size; p = p->next)
num -= p->a->size;
if (num != 1)
{
split(p, num - 1);
p = p->next;
}
return p;
}
PList findr(int num)
{
PList p;
for (p = head; num > p->a->size; p = p->next)
num -= p->a->size;
if (num != p->a->size)
split(p, num);
return p;
}
void balance()
{
PList i;
for (i = head; i; i = i->next)
{
while (i != tail && i->a->size < SQRTN / 2)
merge(i);
if (i->a->size > SQRTN * 2)
split(i, SQRTN);
}
}
int n, m;
int a0[MAXN];
void init()
{
for (tblst = 0; tblst < MAXBL; ++tblst)
blst[tblst] = pool + tblst;
scanf("%d%d", &n, &m);
int i;
for (i = 0; i < n; ++i)
scanf("%d", &a0[i]);
build(a0, n, &head, &tail);
}
void swap(int *a, int *b)
{
int c = *a;
*a = *b;
*b = c;
}
int main()
{
init();
while (m--)
{
char opt[10];
scanf("%s", opt);
if (opt[0] == 'I')
{
int pos, tot, i;
scanf("%d%d", &pos, &tot);
for (i = 0; i < tot; ++i)
scanf("%d", &a0[i]);
PList h2, t2;
build(a0, tot, &h2, &t2);
if (head == NULL)
head = h2, tail = t2;
else if (pos == 0)
{
t2->next = head;
head->last = t2;
head = h2;
}
else if (pos == n)
{
h2->last = tail;
tail->next = h2;
tail = t2;
}
else
{
PList p = findl(pos + 1);
PList p2 = p->last;
h2->last = p2;
p2->next = h2;
t2->next = p;
p->last = t2;
}
n += tot;
}
else if (opt[0] == 'D')
{
int dl, dr;
scanf("%d%d", &dl, &dr);
dr += dl - 1;
PList i;
if (dl == 1 && dr == n)
{
for (i = head; i;)
{
blst[tblst++] = i->a;
PList j = i->next;
free(i);
i = j;
}
head = tail = NULL;
}
else
{
PList fr = findl(dl), en = findr(dr);
if (fr->last)
fr->last->next = en->next;
else
head = en->next;
if (en->next)
en->next->last = fr->last;
else
tail = fr->last;
PList end = en->next;
for (i = fr; i != end;)
{
blst[tblst++] = i->a;
PList j = i->next;
free(i);
i = j;
}
}
n -= dr - dl + 1;
}
else if (opt[0] == 'M' && opt[2] == 'K')
{
int dl, dr, c;
scanf("%d%d%d", &dl, &dr, &c);
dr += dl - 1;
PList fr = findl(dl), en = findr(dr), i;
for (i = fr; i != en->next; i = i->next)
{
i->a->hvsm = 1, i->a->sm = c;
i->a->sum = i->a->size * c;
if (c < 0)
{
i->a->msum = c;
i->a->mmin = i->a->sum;
i->a->mmax = c;
i->a->rmin = i->a->sum;
i->a->rmax = c;
}
else
{
i->a->msum = i->a->sum;
i->a->mmin = c;
i->a->mmax = i->a->sum;
i->a->rmin = c;
i->a->rmax = i->a->sum;
}
}
}
else if (opt[0] == 'R')
{
int dl, dr;
scanf("%d%d", &dl, &dr);
dr += dl - 1;
PList fr = findl(dl), en = findr(dr);
while (fr != en && fr != en->next)
{
fr->a->rev ^= 1;
en->a->rev ^= 1;
swap(&fr->a->mmin, &fr->a->rmin);
swap(&fr->a->mmax, &fr->a->rmax);
swap(&en->a->mmin, &en->a->rmin);
swap(&en->a->mmax, &en->a->rmax);
PBlock tmp = fr->a;
fr->a = en->a;
en->a = tmp;
fr = fr->next;
en = en->last;
}
if (fr == en)
{
fr->a->rev ^= 1;
swap(&fr->a->mmin, &fr->a->rmin);
swap(&fr->a->mmax, &fr->a->rmax);
}
}
else if (opt[0] == 'G')
{
int dl, dr;
scanf("%d%d", &dl, &dr);
dr += dl - 1;
PList fr = findl(dl), en = findr(dr), i;
int ans = 0;
for (i = fr; i != en->next; i = i->next)
ans += i->a->sum;
printf("%d\n", ans);
}
else if (opt[0] == 'M' && opt[2] == 'X')
{
int smin = 0, ans = -INF, sum = 0;
PList i;
for (i = head; i; i = i->next)
{
if (ans < i->a->msum)
ans = i->a->msum;
if (ans < sum + i->a->mmax - smin)
ans = sum + i->a->mmax - smin;
if (smin > sum + i->a->mmin)
smin = sum + i->a->mmin;
sum += i->a->sum;
}
printf("%d\n", ans);
}
balance();
}
return 0;
}