POJ 3468 A Simple Problem with Integers 【splay树入门题】
来源:互联网 发布:振动分析软件 编辑:程序博客网 时间:2024/04/30 11:27
Description
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N,Q。1≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000≤ Ai ≤1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
Sample Input
10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4
Sample Output
455915
由于强大的splay有强大的区间更新功能,完全可以胜任,但是速度慢了好多……对比这篇:
hdu4267A Simple Problem with Integers【树状数组区间更新/单点查询】
注意splay函数while里面的5个push_down模板上有是由于存在反转操作,对于本题而言就不能再算进去了==
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>using namespace std;#define Key_value ch[ch[root][1]][0]const int MAXN=500010;const int INF=0x3f3f3f3f;int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN];int rev[MAXN],same[MAXN];int lx[MAXN],rx[MAXN],mx[MAXN];int root,tot1;int s[MAXN],tot2;int a[MAXN];int n,q;long long sum[MAXN];//debug部分void Treavel(int x){ if(x) { Treavel(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d, size= %2d, sum=%2d,rev=%2d same=%2d lx=%2d rx=%2d mx=%2d\n",x,ch[x][0],ch[x][1],pre[x],key[x],size[x],sum[x],rev[x],same[x],lx[x],rx[x],mx[x]); Treavel(ch[x][1]); }}void debug(){ printf("root%d\n",root); Treavel(root);}void NewNode(int &r,int father,int k){ if(tot2)r=s[tot2--]; else r=++tot1; pre[r]=father; ch[r][0]=ch[r][1]=0; key[r]=k; sum[r]=k; rev[r]=same[r]=0; lx[r]=rx[r]=mx[r]=k; size[r]=1;}void Update_Same(int r,int v){ if(!r)return; key[r]+=v; sum[r]+=(long long)v*size[r]; //Update_Same(ch[r][0],v); //Update_Same(ch[r][1],v); // lx[r]=rx[r]=mx[r]=max(v,sum[r]); same[r]+=v;}void Update_Rev(int r){ if(!r)return; swap(ch[r][0],ch[r][1]); swap(lx[r],rx[r]); rev[r]^=1;//这里要注意,一定是异或1}void Push_Up(int r){ int lson=ch[r][0],rson=ch[r][1]; size[r]=size[lson]+size[rson]+1; sum[r]=sum[lson]+sum[rson]+key[r];// lx[r]=max(lx[lson],sum[lson]+key[r]+max(0,lx[rson]));// rx[r]=max(rx[rson],sum[rson]+key[r]+max(0,rx[lson]));// mx[r]=max(0,rx[lson])+key[r]+max(0,lx[rson]);// mx[r]=max(mx[r],max(mx[lson],mx[rson]));}void Push_Down(int r){ if(same[r]) { Update_Same(ch[r][0],same[r]);/// Update_Same(ch[r][1],same[r]); same[r]=0; } if(rev[r]) { Update_Rev(ch[r][0]); Update_Rev(ch[r][1]); rev[r]=0; }}void Build(int &x,int l,int r,int father){ if(l>r)return; int mid=(l+r)/2; NewNode(x,father,a[mid]); Build(ch[x][0],l,mid-1,x); Build(ch[x][1],mid+1,r,x); Push_Up(x);}void Init(){ root=tot1=tot2=0; ch[root][0]=ch[root][1]=pre[root]=size[root]=same[root]=rev[root]=sum[root]=key[root]=0;// lx[root]=rx[root]=mx[root]=-INF; NewNode(root,0,-1); NewNode(ch[root][1],root,-1); for(int i=1;i<=n;i++)scanf("%d",&a[i]);/// Build(Key_value,1,n,ch[root][1]); Push_Up(ch[root][1]); Push_Up(root);}void Rotate(int x,int kind){ int y=pre[x]; Push_Down(y); Push_Down(x); 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 r,int goal){ Push_Down(r); while(pre[r]!=goal) { if(pre[pre[r]]==goal) { // Push_Down(pre[r]); // Push_Down(r); Rotate(r,ch[pre[r]][0]==r); } else { // Push_Down(pre[pre[r]]); // Push_Down(pre[r]); // Push_Down(r); int y=pre[r]; int kind=ch[pre[y]][0]==y; if(ch[y][kind]==r) { Rotate(r,!kind); Rotate(r,kind); } else { Rotate(y,kind); Rotate(r,kind); } } } Push_Up(r); if(goal==0)root=r;}int Get_Kth(int r,int k){ Push_Down(r); int t=size[ch[r][0]]+1; if(t==k)return r; if(t>k)return Get_Kth(ch[r][0],k); else return Get_Kth(ch[r][1],k-t);}////在第pos个数后插入tot个数//void Insert(int pos,int tot)//{// for(int i=0;i<tot;i++)scanf("%d",&a[i]);// Splay(Get_Kth(root,pos+1),0);// Splay(Get_Kth(root,pos+2),root);// Build(Key_value,0,tot-1,ch[root][1]);// Push_Up(ch[root][1]);// Push_Up(root);//}//void erase(int r)//{// if(!r)return;// s[++tot2]=r;// erase(ch[r][0]);// erase(ch[r][1]);//}////从第pos个数开始连续删除tot个数//void Delete(int pos,int tot)//{// Splay(Get_Kth(root,pos),0);// Splay(Get_Kth(root,pos+tot+1),root);// erase(Key_value);// pre[Key_value]=0;// Key_value=0;// Push_Up(ch[root][1]);// Push_Up(root);//}//从第pos个数连续开始的tot个数修改为cvoid Make_Same(int pos,int tot,int c){ Splay(Get_Kth(root,pos),0); Splay(Get_Kth(root,pos+tot+1),root); Update_Same(Key_value,c); Push_Up(ch[root][1]); Push_Up(root);}////反转//void Reverse(int pos,int tot)//{// Splay(Get_Kth(root,pos),0);// Splay(Get_Kth(root,pos+tot+1),root);// Update_Rev(Key_value);// Push_Up(ch[root][1]);// Push_Up(root);//}//求和long long Get_Sum(int pos,int tot){ Splay(Get_Kth(root,pos),0); Splay(Get_Kth(root,pos+tot+1),root); return sum[Key_value];}////得到最大和//int Get_MaxSum(int pos,int tot)//{// Splay(Get_Kth(root,pos),0);// Splay(Get_Kth(root,pos+tot+1),root);// return mx[Key_value];//}void Inorder(int r){ if(!r)return; Push_Down(r); Inorder(ch[r][0]); printf("%d ",key[r]); Inorder(ch[r][1]);}int main(){ //freopen("cin.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&q)) { Init(); char op[20]; int x,y,z; while(q--) { scanf("%s",op);// if(op[0]=='I')// {// scanf("%d%d",&x,&y);// Insert(x,y);// }// else if(op[0]=='D')// {// scanf("%d%d",&x,&y);// Delete(x,y);// } if(op[0]=='C') { scanf("%d%d%d",&x,&y,&z); Make_Same(x,y-x+1,z); }// else if(op[0]=='R')// {// scanf("%d%d",&x,&y);// Reverse(x,y);// } else if(op[0]=='Q') { scanf("%d%d",&x,&y); printf("%I64d\n",Get_Sum(x,y-x+1)); }// else// {// printf("%d\n",Get_MaxSum(1,size[root]-2));// } } } return 0;}
0 0
- POJ 3468 A Simple Problem with Integers 【splay树入门题】
- poj 3468 A Simple Problem with Integers (Splay树)
- POJ 3468 A Simple Problem with Integers (Splay树练习)
- poj-3468-A Simple Problem with Integers-splay树
- [POJ 3468] A Simple Problem with Integers Splay树
- POJ 3468 A Simple Problem with Integers Splay
- POJ 3468 A Simple Problem with Integers ( Splay )
- 【Splay】POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers splay
- poj 3468 A Simple Problem with Integers splay tree
- POJ 3468 A Simple Problem with Integers (splay)
- poj 3468 A Simple Problem with Integers - Splay
- POJ-3468 A Simple Problem with Integers(Splay实现)
- poj 3468 A Simple Problem with Integers splay
- A Simple Problem with Integers+poj+splay树区间操作
- POJ A Simple Problem with Integers (Splay 伸展树 入门)
- poj 3468 A Simple Problem with Integers(splay tree模板题)
- POJ 3468 A simple problem with integers Splay 区间维护模板题
- 01-jsonp学习
- 在java中除去字符串(String)中的换行字符(\r \n \t)
- 第七周友元函数求两点间距离
- JavaScript之数组
- 分数类的雏形
- POJ 3468 A Simple Problem with Integers 【splay树入门题】
- 【poj 2411】Mondriaan's Dream 状态压缩DP
- MyBatis 3 用户指南
- SCOI2016酱油记
- CSS3之弹性盒模型
- hdu 【2115】 C Looooops
- 第六周项目1-分数类的锥形
- jquery跨域ajax访问方法
- 启动weblogic的遇见的一些问题及解决方案(环境为win 10 64位,weblogic 12.2.1)