POJ 3468 splay

A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 54382 Accepted: 16350
Case Time Limit: 2000MS

Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.
照着练一下splay。
代码:
/* ***********************************************
Author :rabbit
Created Time :2014/3/22 15:21:19
File Name :13.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
#define keytree ch[ch[root][1]][0]
const ll maxn=200100;
struct splay{
	ll sz[maxn],ch[maxn][2],pre[maxn];
	ll root,top1,top2;
	ll ss[maxn],que[maxn];
	void Rotate(ll x,ll f){
		ll y=pre[x];
		pushdown(y);
		pushdown(x);
		ch[y][!f]=ch[x][f];
		pre[ch[x][f]]=y;
		pre[x]=pre[y];
		if(pre[x])ch[pre[y]][ch[pre[y]][1]==y]=x;
		ch[x][f]=y;
		pre[y]=x;
		pushup(y);
	}
	void Splay(ll x,ll goal){
		pushdown(x);
		while(pre[x]!=goal){
			if(pre[pre[x]]==goal)Rotate(x,ch[pre[x]][0]==x);
			else{
				ll y=pre[x],z=pre[y];
				ll f=ch[z][0]==y;
				if(ch[y][f]==x)Rotate(x,!f),Rotate(x,f);
				else Rotate(y,f),Rotate(x,f);
			}
		}
		pushup(x);
		if(goal==0)root=x;
	}
	void RTO(ll k,ll goal){
		ll x=root;
		pushdown(x);
		while(sz[ch[x][0]]!=k){
			if(k<sz[ch[x][0]])x=ch[x][0];
			else{
				k-=sz[ch[x][0]]+1;
				x=ch[x][1];
			}
			pushdown(x);
		}
		Splay(x,goal);
	}
	void erase(ll x){
		ll father=pre[x];
		ll head=0,tail=0;
		for(que[tail++]=x;head<tail;head++){
			ss[top2++]=que[head];
			if(ch[que[head]][0])que[tail++]=ch[que[head]][0];
			if(ch[que[head]][1])que[tail++]=ch[que[head]][1];
		}
		ch[father][ch[father][1]==x]=0;
		pushup(father);
	}
	void debug(){
		printf("%lld\n",root);
		Traval(root);
	}
	void Traval(ll x){
		if(x){
			Traval(ch[x][0]);
            printf("结点%2lld:左儿子 %2lld 右儿子 %2lld 父结点 %2lld size = %2lld ,val = %2lld\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]);
			Traval(ch[x][1]);	
		}
	}
	ll val[maxn],num[maxn],add[maxn],sum[maxn];
	void Newnode(ll &x,ll c){
		if(top2)x=ss[--top2];else x=++top1;
		ch[x][0]=ch[x][1]=pre[x]=0;
		sz[x]=1;
		val[x]=sum[x]=c;
		add[x]=0;
	}
	void pushdown(ll x){
		if(add[x]){
			val[x]+=add[x];
			add[ch[x][0]]+=add[x];
			add[ch[x][1]]+=add[x];
			sum[ch[x][0]]+=sz[ch[x][0]]*add[x];
			sum[ch[x][1]]+=sz[ch[x][1]]*add[x];
			add[x]=0;
		}
	}
	void pushup(ll x){
		sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];
		sum[x]=add[x]+val[x]+sum[ch[x][0]]+sum[ch[x][1]];
	}
	void Build(ll &x,ll l,ll r,ll f){
		if(l>r)return;
		ll m=(l+r)/2;
		Newnode(x,num[m]);
		Build(ch[x][0],l,m-1,x);
		Build(ch[x][1],m+1,r,x);
		pre[x]=f;
		pushup(x);
	}
	void init(ll n){
		ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;
		add[0]=sum[0]=0;
		Newnode(root,-1);
		Newnode(ch[root][1],-1);
		pre[top1]=root;
		sz[root]=2;
		for(ll i=0;i<n;i++)scanf("%lld",&num[i]);
		Build(keytree,0,n-1,ch[root][1]);
		pushup(ch[root][1]);
		pushup(root);
	}
	void update(ll l,ll r,ll c){
		RTO(l-1,0);
		RTO(r+1,root);
		add[keytree]+=c;
		sum[keytree]+=c*sz[keytree];
	}
	ll query(ll l,ll r){
		RTO(l-1,0);
		RTO(r+1,root);
		return sum[keytree];
	}
}spt;
int main()
{
     //freopen("data.in","r",stdin);
     //freopen("data.out","w",stdout);
     ll n,m;
	 while(~scanf("%lld%lld",&n,&m)){
		spt.init(n);
		while(m--){
			char op[2];
			scanf("%s",op);
			if(op[0]=='Q'){
				ll l,r,c;
				scanf("%lld%lld",&l,&r);
				printf("%lld\n",spt.query(l,r));
			}
			else{
				ll l,r,c;
				scanf("%lld%lld%lld",&l,&r,&c);
				spt.update(l,r,c);
			}
		}
	 }
     return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值