Topic Connection
Title Description
time limit: 10000ms
single point time limit: 1000ms
memory limit: 256MB
Problem Solving Ideas:
The direct violence at each point in time is obviously the tle, and now it is not considered at the point of time, but in what time points each unit of magic is extracted, so that each unit has a set of time intervals to be drawn, and each magic unit has a maximum of M and a recovery speed R, Consider a set of time intervals for a magic unit A, sorted by size: greater than or equal to (m+r-1)/R: means that the mana extracted is the mana limit M, and if there is a k time interval to satisfy the condition, the sum of the magical values extracted by this part is k*m. less than (m+r-1)/R: sum multiplied by R is the total mana extracted from that part. The sum of the total mana extracted from these two parts is the total mana extracted by a mana unit. All units of magic are so considered and summed up.
The key here is how to maintain these intervals, first of all to maintain the point at which each magic unit has been extracted, and then to maintain the interval based on these points in time.
Point-in- time maintenance : Using a stretch tree a, for each of the Magic unit 1-n I, the operation time to start interval I into the extension tree A, a maintenance process to ensure the order of time , in fact, is a binary sorting tree, After the insert is complete, a maintains all points of time for the extraction operation of the Magic Unit I.
If, at the same time as inserting a point B, the first and subsequent C of the sequence traversal of the point is taken, it means that for the time interval of I and the subsequent magic units , there is a decrease: c-a, which adds two: B-a and C-b.
and after the extraction and settlement of the Magic Unit I , remove all the operation point B from a to end the interval, also get precursor A and successor C, which means that the time interval of the magic unit after I decreased by two: C-b and B-a, added one: c-a.
time interval maintenance: still using a stretch number b,b maintains the time interval (same order), and maintains additional information, all the time interval sum sums, and the number of all time intervals is size.
For the previous point-in-time maintenance, each a insertion will result in a B delete and two b insertions;
Also every a delete, will result in two B deletions and a B insertion. Code:
#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <set> #
Include <cmath> #include <algorithm> using namespace std;
#define MAXN 500005 typedef long Long int ll64;
typedef unsigned long long int ll65;
Const LL65 INFT = (1e9) + 1; typedef struct ope{ll65 s, M, R;}
Ope
typedef struct stree{typedef struct node{struct node *ch[2], *pre;
LL65 tmseg, size, num, sums;
}node;
Node buf[maxn*2], *root, *nil;
int bufsize;
Node *getnode (ll65 tmseg, node* fa) {node *p = NULL;
if (bufsize<maxn*2) {p = buf + bufsize++;}
else{p = (node*) malloc (sizeof (node));}
P->ch[0] = p->ch[1] = nil;
p->tmseg = P->sums = tmseg;
P->pre = FA;
P->size = P->num = 1;
return p;
} inline int Update (node *x) {if (x->num<0) x->num=0; X->size=x->ch[0]->size+x->ch[1]->size+x->num;
x->sums=x->ch[0]->sums+x->ch[1]->sums+x->num*x->tmseg;
return 0;
} int init () {bufsize = 0;
Nil = getnode (0, NULL);
Nil->ch[0] = nil->ch[1] = NULL;
nil->size = Nil->num = 0;
root = getnode (0, nil);
ROOT->CH[1] = GetNode (Inft, Root);
Update (root);
return 0;
} int Rotateto (node *x, int to) {Node *XF = x->pre;
xf->ch[to ^ 1] = x->ch[to];
xf->ch[to ^ 1]->pre = XF;
X->pre = xf->pre;
if (xf->pre->ch[0] = = XF) x->pre->ch[0] = x;
else x->pre->ch[1] = x; Xf->pre = x;
X->ch[to] = XF;
Update (XF);
if (xf==root) root=x;
return 0;
} int splay (node *x, node *fa) {while (x->pre! = FA) {if (X->pre->pre = = FA) {
if (x->pre->ch[0] = = x) rotateto (x, 1); else Rotateto (x, 0); } else{if (x->pre->pre->ch[0] = = X->pre) {if (x->pre->c
H[0] = = x) {Rotateto (x->pre, 1); Rotateto (x, 1);}
else {rotateto (x, 0); Rotateto (x, 1);}
} else{if (x->pre->ch[0] = = x) {Rotateto (x, 1); Rotateto (x, 0);}
else {rotateto (x->pre, 0); Rotateto (x, 0);}
}}} update (x);
return 0;
} int Select (ll65 value,ll65 &size1,ll65 &size2) {node *p = root,*q=null;
while (P! = nil) {if (p->tmseg = = value) break;
else if (P->tmseg > value) {q = p; p = p->ch[0];}
else {q = p; p = p->ch[1];}
} if (p = = nil) {splay (q, nil);
if (Q->tmseg < value) {p=root->ch[1]; while (P->ch[0]!=nil) {p=p->ch[0];}
Splay (P, nil);
}}else{splay (P, nil);
} size1 = root->ch[0]->sums;
Size2 = root->size-root->ch[0]->size-1;
return 0;
} int Insert (LL65 value) {node *p = root, *q = NULL;
if (value==0) return 0;
while (P! = nil) {if (p->tmseg = = value) break;
else if (P->tmseg > value) {q = p; p = p->ch[0];}
else {q = p; p = p->ch[1];}
if (P! = nil) {p->num + = 1;
P->size + = 1;
P->sums + = value;
Splay (P, nil);
} else{p = getnode (value, q);
if (value<q->tmseg) q->ch[0] = p;
else q->ch[1] = p;
Splay (P, nil);
} return 0;
} int Remove (ll65 value) {node *p = root, *q = NULL;
if (value==0) return 0; while (P! = nil) {if (p->tmseg = = value) break;
else if (P->tmseg > value) {q = p; p = p->ch[0];}
else {q = p; p = p->ch[1];}
} if (P! = nil) {p->num-= 1;
P->size-= 1;
P->sums-= value;
Splay (P, nil);
} return 0;
}}stree;
typedef struct stree1{typedef struct node{struct node *pre, *ch[2];
LL65 TM;
}node;
Node Buf[maxn*4], *root, *nil;
int bufsize;
Node *getnode (ll65 Value, node *fa) {node *p = NULL;
if (bufsize<maxn*4) p = buf + bufsize++;
else P = (node*) malloc (sizeof (node)); P->pre = FA;
P->tm = value;
P->ch[0] = p->ch[1] = nil;
return p;
} int init () {bufsize = 0;
nil = NULL;
Nil = getnode (0, NULL);
Nil->ch[0] = nil->ch[1] = NULL;
NIL->TM = 0;
root = getnode (0, nil); ROOT->CH[1] = GetNode (inFT, Root);
return 0;
} int Rotateto (node *x, int to) {Node *XF = x->pre;
xf->ch[to ^ 1] = x->ch[to];
xf->ch[to ^ 1]->pre = XF;
X->pre = xf->pre;
if (xf->pre->ch[0] = = XF) x->pre->ch[0] = x;
else x->pre->ch[1] = x; Xf->pre = x;
X->ch[to] = XF;
if (xf==root) root=x;
return 0;
} int splay (node *x, node *fa) {while (x->pre! = FA) {if (X->pre->pre = = FA) {
if (x->pre->ch[0] = = x) rotateto (x, 1);
else Rotateto (x, 0); } else{if (x->pre->pre->ch[0] = = X->pre) {if (x->pre->c
H[0] = = x) {Rotateto (x->pre, 1); Rotateto (x, 1);}
else {rotateto (x, 0); Rotateto (x, 1);}
} else{if (x->pre->ch[0] = = x) {Rotateto (x, 1); Rotateto (x, 0);} else {rotateto (x->pre, 0); Rotateto (x, 0);}
}}} return 0;
} int Insert (LL65 TM, Ll65 &a, ll65 &b, ll65 &c) {node *p = root, *q = NULL;
if (tm==0) return 0;
while (P! = nil) {if (P->tm = = tm) break;
else if (P->tm > tm) {q = p; p = p->ch[0];}
else {q = p; p = p->ch[1];}
} if (p = = nil) {P=getnode (tm,q);
if (tm > Q->tm) {q->ch[1]=p;
}else q->ch[0]=p; Splay (P, nil);
B=tm; p=root->ch[0];
while (P->ch[1]!=nil) p=p->ch[1];
a=p->tm; p=root->ch[1];
while (P->ch[0]!=nil) p=p->ch[0];
c=p->tm;
return 1;
} else return 0;
return 0;
} int Remove (LL65 TM, Ll65 &a, ll65 &b, ll65 &c) {node *p = root, *q = NULL; If(tm==0) return 0;
while (P! = nil) {if (P->tm = = tm) break;
else if (P->tm > tm) {q = p; p = p->ch[0];}
else {q = p; p = p->ch[1];}
} if (P! = nil) {splay (P, nil);
Node *P1 = p->ch[0];
while (p1->ch[1]! = nil) P1 = p1->ch[1];
Node *P2 = p->ch[1];
while (p2->ch[0]! = nil) P2 = p2->ch[0]; Splay (P1, nil);
Splay (P2, root); A = p1->tm; b = TM;
c = p2->tm;
P2->ch[0] = nil;
return 1;
} else return 0;
return 0;
} int getmin () {node *p = root, *q = root;
while (p->ch[0]!=nil) {p = p->ch[0];
} if (P->ch[1]==nil) {q=p->pre;
}else{q=p->ch[1];
while (Q->ch[0]!=nil) q=q->ch[0];
} return q->tm;
}}stree1; Vector<ll65> Stm[maXN], ETM[MAXN];
Ope OP[MAXN],OPR[MAXN];
int oprcmp (const ope &a,const ope &b) {if (a.m. = = B.M) return a.r<b.r;
Return a.m<b.m;
} int main () {ll65 I, j, K;
Ll65 N, M, L, R, T;
Freopen ("In.txt", "R", stdin);
Freopen ("OUT.txt", "w", stdout);
scanf ("%llu", &n);
for (i = 1; I <= n; i++) {scanf ("%llu%llu%llu", &op[i].s, &OP[I].M, &OP[I].R);
} scanf ("%llu", &m); i=0;
K=1;j=1;
int flag0=0;
scanf ("%llu%llu%llu", &opr[i].s, &OPR[I].M, &OPR[I].R);
int tst=0,ted=0;
for (i =1; i<m; i++) {scanf ("%llu%llu%llu", &opr[j].s, &OPR[J].M, &OPR[J].R);
if (opr[j].s! = opr[j-1].s) {if (TED>TST) {sort (opr+tst,opr+ted+1,oprcmp);
int ii,jj=tst; for (ii =tst+1;ii<=ted;ii++) {if (opr[ii].m<= opr[jj].r+1) {Opr[jj].r=max
(OPR[JJ].R,OPR[II].R); }else{++JJ; OPR[JJ]=OPR[II]; }} ++JJ;
OPR[JJ]=OPR[J]; TST=TED=JJ;
j=jj+1;
}else{tst=ted=j;
j + +;
}}else{ted=j;
j + +;
}} if (TED>TST) {sort (opr+tst,opr+ted+1,oprcmp);
int II, JJ=TST; for (ii =tst+1;ii<=ted;ii++) {if (opr[ii].m<= opr[jj].r+1) {Opr[jj].r=max (opr[jj].r,opr[i
I].R);
}else{++JJ;
OPR[JJ]=OPR[II];
}} TED=JJ;
} for (i=0;i<=ted;i++) {stm[opr[i].m].push_back (OPR[I].S);
Etm[opr[i].r].push_back (OPR[I].S);
} stree *t1 = new Stree;
Stree1*t2 = new Stree1; T1->init ();
T2->init ();
Ll65 A, B, C;
Ll65 ans = 0;
int ret=0,tmpcnt=0; for (i = 1; I <= N, i++) {for (j = 0; J<stm[i].size (); j + +) {if (stm[i][j]==0) flag0= 1;
tmpcnt++;
Ret=t2->insert (Stm[i][j], A, b, c);
cout<< "Insert:" <<a<< "" <<b<< "" <<c<<endl;
if (ret==1) {//cout<<a<< "" <<b<< "" <<c<<endl;
if (c! = Inft) {t1->remove (c-a);
T1->insert (C-b);
} t1->insert (B-A);
}}//cout<<t1->root->sums<<endl;
if (tmpcnt>0) if (op[i].m>0) {if (op[i].r>0) {ll65 mint = t2->getmin ();
if (flag0==1) mint=0;
LL65 size1, Size2;
LL65 tmp= (op[i].m + op[i].r-1)/OP[I].R;
T1->select (TMP, SIZE1, size2);
if (Mint < tmp) {size1-= mint;
}else size2--;
Ans + = SIZE1*OP[I].R + size2*op[i].m;
tmp= (Op[i].m-op[i].s + op[i].r-1)/OP[I].R;
if (Mint < tmp) {ans + + MINT*OP[I].R + op[i].s;
} else ans + = op[i].m;
}else{Ans+=op[i].s;
}}//cout<< "id =" <<i<< ": ans=" <<ans<<endl;
for (j = 0; J < Etm[i].size (); j + +) {if (etm[i][j]==0) flag0=0;
tmpcnt--;
int Ret=t2->remove (ETM[I][J],A,B,C);
cout<< "Remove:" <<a<< "<<b<<" "<<c<<endl;
if (ret) {t1->remove (b-a);
if (c! = Inft) {t1->remove (c-b);
T1->insert (C-A);
}}}} printf ("%llu\n", ans);
return 0;
}