当前位置: 代码迷 >> 综合 >> poj-3468-A Simple Problem with Integers-splay树
  详细解决方案

poj-3468-A Simple Problem with Integers-splay树

热度:90   发布时间:2023-12-19 10:42:07.0

原本应该是线段树板刷的题目,现在用splay tree来做一下。就当练练手。

建立初始树的时候按照顺序建立的二叉树。

每个节点存储的信息:

int pre[maxn];     当前节点的前驱

int ch[maxn][2];当前节点的左右子树

int val[maxn];当前节点的值

int size[maxn];当前节点的子树的节点个数

int add[maxn];当前节点的子树被增加的值

LL sum[maxn];当前节点的子树的总值

当Q X Y的时候,就把x-1节点设置成根节点。y+1节点设置成根节点的右子树。

那么sum[ch[ch[root][1]][0]]即为结果。

当C X Y k的时候,就把x-1节点设置成根节点。y+1节点设置成根节点的右子树。

然后add[ch[ch[root][1]][0]]+=k;

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 110000
#define LL long long
struct splaytree
{int a[maxn];int pre[maxn];int ch[maxn][2];int val[maxn];int root,tot,n;int size[maxn];int add[maxn];LL sum[maxn];void init(){memset(pre,0,sizeof(pre));memset(ch,0,sizeof(ch));memset(size,0,sizeof(size));memset(add,0,sizeof(add));memset(sum,0,sizeof(sum));memset(val,0,sizeof(val));root=tot=0;start();}void newnode(int &r,int father,int k){r=++tot;pre[r]=father;add[r]=0;sum[r]=k;val[r]=k;ch[r][0]=ch[r][1]=0;size[r]=1;}void push_up(int x){size[x]=size[ch[x][1]]+size[ch[x][0]]+1;sum[x]=sum[ch[x][1]]+sum[ch[x][0]]+add[x]+val[x];}void push_down(int x){val[x]+=add[x];add[ch[x][1]]+=add[x];add[ch[x][0]]+=add[x];sum[ch[x][1]]+=(LL)add[x]*size[ch[x][1]];sum[ch[x][0]]+=(LL)add[x]*size[ch[x][0]];add[x]=0;}void rot(int x,int kind){int y=pre[x];push_down(x);push_down(y);ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;push_up(y);}void splay(int x,int goal){push_down(x);while(pre[x]!=goal){if(pre[pre[x]]==goal)rot(x,ch[pre[x]][0]==x);else{int y=pre[x];int kind=ch[pre[y]][0]==y;if(ch[y][kind]==x){rot(x,!kind);rot(x,kind);}else{rot(y,kind);rot(x,kind);}}}push_up(x);if(goal==0)root=x;}void rotto(int x,int goal){int r=root;push_down(r);while(size[ch[r][0]]!=x){if(x<size[ch[r][0]])r=ch[r][0];else{x=x-size[ch[r][0]]-1;r=ch[r][1];}push_down(r);}splay(r,goal);}void update(int l,int r){int k;scanf("%d",&k);rotto(l-1,0);rotto(r+1,root);add[ch[ch[root][1]][0]]+=k;sum[ch[ch[root][1]][0]]+=size[ch[ch[root][1]][0]]*k;}LL query(int l,int r){rotto(l-1,0);rotto(r+1,root);return sum[ch[ch[root][1]][0]];}void buildtree(int &x,int l,int r,int father){if(l>r)return;int mid=(l+r)/2;newnode(x,father,a[mid]);if(l<mid)buildtree(ch[x][0],l,mid-1,x);if(r>mid)buildtree(ch[x][1],mid+1,r,x);push_up(x);}void start(){for(int i=0;i<n;i++)scanf("%d",&a[i]);newnode(root,0,-1);newnode(ch[root][1],root,-1);size[root]=2;buildtree(ch[ch[root][1]][0],0,n-1,ch[root][1]);push_up(ch[root][1]);push_up(root);}
}T;
int main()
{int n,q;while(~scanf("%d%d",&n,&q)){T.n=n;T.init();while(q--){char str[10];int x,y;scanf("%s%d%d",str,&x,&y);if(str[0]=='Q')printf("%lld\n",T.query(x,y));elseT.update(x,y);}}return 0;
}


  相关解决方案