http://poj.org/problem?id=3468
写完后发现用指针的速度比数组快了一秒。。。。。
等有空把那个维修数列也写一写试一下,不知道能跑多快
贴一下一个下午的成果吧,总感觉代码量上还可以精简,,,,求路过的神牛指导啊
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lld;
#define L x->c[0]
#define R x->c[1]
#define KT root->c[1]->c[0]
const int maxn = 100010;
struct node {
struct node *c[2] , *fa;
int id ;
int sz;
int val;
int add;
lld sum;
void down(){
if(add) {
if(c[0]) {
c[0]->val += add;
c[0]->add += add;
c[0]->sum += (lld)add * c[0]->sz;
}
if(c[1]) {
c[1]->val += add;
c[1]->add += add;
c[1]->sum += (lld)add * c[1]->sz;
}
add = 0;
}
}
void up() {
sz = c[0]->sz + c[1]->sz + 1;
sum= val + c[0]->sum + c[1]->sum;
}
}*root,NODE[maxn],*null=&NODE[0];
int num[maxn] , n , top;
struct SplayTree{
void Rotate(node *x,int f) {
node *y = x->fa;
y->down(); x->down();
y->c[!f] = x->c[f];
x->c[f]->fa = y;
x->fa = y->fa;
if(x->fa != null) y->fa->c[ y->fa->c[1] == y ] = x;
x->c[f] = y;
y->fa = x;
y->up();
}
void Splay(node *x,node *goal) {
x->down();
while(x->fa != goal) {
if(x->fa->fa == goal) Rotate(x,x->fa->c[0] == x);
else {
node *y = x->fa , *z = y->fa;
int f = (z->c[0] == y);
y->c[f]==x ? Rotate(x,!f) :Rotate(y,f);
Rotate(x,f);
}
}
x->up();
if(goal == null) root = x;
}
void RTO(int k,node *goal) {
node *x = root;
x->down();
while(L->sz + 1 != k) {
if(k < L->sz + 1) x = L;
else{
k -= L->sz + 1;
x = R;
}
x->down();
}
Splay(x,goal);
}
node *new_node(node *fa,int v) {
node *x=&NODE[++top];
x->id = top;
x->c[0] = x->c[1] = null;
x->sz = 1;
x->val = x->sum = v;
x->add = 0;
x->fa = fa;
return x;
}
void build(node* &x,int l,int r,node *fa) {
if(l > r) return ;
int m = l + r>>1;
x = new_node(fa,num[m]);
build(x->c[0],l,m-1,x);
build(x->c[1],m+1,r,x);
x->up();
}
void vist(node *x) {
if(x!=null){
printf("节点:%2d : 左儿子: %2d 右儿子: %2d sz: %2d sum: %2lld\n",
x->id,x->c[0]->id,x->c[1]->id,x->sz,x->sum);
vist(x->c[0]);
vist(x->c[1]);
}
}
void init(int n) {
top = 0;
null->id = 0;
null->c[0] = null->c[1] = null->fa = NULL;
null->sz = null->add = null->sum = null->val = 0;
root = new_node(null,-1);
root->c[1] = new_node(root,-1);
root->sz = 2;
for(int i = 1; i <= n; i++) scanf("%d",&num[i]);
build(KT,1,n,root->c[1]);
root->c[1]->up(); root->up();
}
void update(){
int l ,r , c;
scanf("%d%d%d",&l,&r,&c);
RTO(l,null);
RTO(r+2,root);
KT->add += c;
KT->val += c;
KT->sum += (lld)c * KT->sz;
}
void query() {
int l ,r ;
scanf("%d%d",&l,&r);
RTO(l,null);
RTO(r+2,root);
printf("%I64d\n",KT->sum);
}
}spt;
int main() {
char op[10];
int m;
scanf("%d%d",&n,&m);
spt.init(n);
for(int i=0;i<m;i++) {
scanf("%s",op);
if(op[0] == 'Q')spt.query();
else spt.update();
}
return 0;
}