Uva 12436 Rip Van Winkle's Code
2015-07-26 20:37
323 查看
Rip Van Winkle was fed up with everything except programming. One day he found a problem whichrequired to perform three types of update operations (A, B, C), and one query operation S over an arraydata[]. Initially all elements of data are equal to 0. Though
Rip Van Winkle is going to sleep for 20years, and his code is also super slow, you need to perform the same update operations and output theresult for the query operation S in an efficient way.
long long data[250001];
void A( int st, int nd ) {
for( int i = st; i \le nd; i++ ) data[i] = data[i] + (i - st + 1);
}
void B( int st, int nd ) {
for( int i = st; i \le nd; i++ ) data[i] = data[i] + (nd - i + 1);
}
void C( int st, int nd, int x ) {
for( int i = st; i \le nd; i++ ) data[i] = x;
}
long long S( int st, int nd ) {
long long res = 0;
for( int i = st; i \le nd; i++ ) res += data[i];
return res;
}
Input
The first line of input will contain T (≤ 4 ∗ 105) denoting the number of operations. Each of the nextT lines starts with a character (‘A’, ‘B’, ‘C’ or ‘S’), which indicates the type of operation. Character ‘A’,‘B’ or ‘S’ will be followed by two integers,
st and nd in the same line. Character ‘C’ is followed by threeintegers, st, nd and x. It’s assumed that, 1 ≤ st ≤ nd ≤ 250000 and −105 ≤ x ≤ 105. The meaningsof these integers are explained by the code of Rip Van Winkle.
Output
For each line starting with the character ‘S’, print S(st, nd) as defined in the code.
Sample Input
7
A 1 4
B 2 3
S 1 3
C 3 4 -2
S 2 4
B 1 3
S 2 4
Sample Output
9
0
3
这题是区间更新,这题比较麻烦,做了很长时间。先用线段树维护l,r,add1(线段左端点加的值),add2(线段右端点加的值),step(区间的公差,右边减去左边的),sum(区间总和),flag(判断区间是否数字相同),value(区间数字都相同时的数值大小).
Rip Van Winkle is going to sleep for 20years, and his code is also super slow, you need to perform the same update operations and output theresult for the query operation S in an efficient way.
long long data[250001];
void A( int st, int nd ) {
for( int i = st; i \le nd; i++ ) data[i] = data[i] + (i - st + 1);
}
void B( int st, int nd ) {
for( int i = st; i \le nd; i++ ) data[i] = data[i] + (nd - i + 1);
}
void C( int st, int nd, int x ) {
for( int i = st; i \le nd; i++ ) data[i] = x;
}
long long S( int st, int nd ) {
long long res = 0;
for( int i = st; i \le nd; i++ ) res += data[i];
return res;
}
Input
The first line of input will contain T (≤ 4 ∗ 105) denoting the number of operations. Each of the nextT lines starts with a character (‘A’, ‘B’, ‘C’ or ‘S’), which indicates the type of operation. Character ‘A’,‘B’ or ‘S’ will be followed by two integers,
st and nd in the same line. Character ‘C’ is followed by threeintegers, st, nd and x. It’s assumed that, 1 ≤ st ≤ nd ≤ 250000 and −105 ≤ x ≤ 105. The meaningsof these integers are explained by the code of Rip Van Winkle.
Output
For each line starting with the character ‘S’, print S(st, nd) as defined in the code.
Sample Input
7
A 1 4
B 2 3
S 1 3
C 3 4 -2
S 2 4
B 1 3
S 2 4
Sample Output
9
0
3
这题是区间更新,这题比较麻烦,做了很长时间。先用线段树维护l,r,add1(线段左端点加的值),add2(线段右端点加的值),step(区间的公差,右边减去左边的),sum(区间总和),flag(判断区间是否数字相同),value(区间数字都相同时的数值大小).
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; #define maxn 250060 #define ll long long ll sum; struct node{ ll l,r,add1,add2,step,sum,flag,v; //全改成long long }b[8*maxn]; void build(ll l,ll r,ll i) { ll mid; b[i].l=l;b[i].r=r; b[i].add1=b[i].add2=b[i].step=0; b[i].flag=0; b[i].sum=b[i].v=0; if(l==r)return; mid=(l+r)/2; build(l,mid,i*2); build(mid+1,r,i*2+1); } void pushdown(ll i) { ll mid,add1,add2,add3,add4; mid=(b[i].l+b[i].r)/2; if(b[i].l==b[i].r)return; if(b[i].flag==0){ b[i*2].flag=b[i*2+1].flag=0; b[i*2].v=b[i*2+1].v=b[i].v; b[i*2].add1=b[i*2].add2=b[i*2+1].add1=b[i*2+1].add2=0; b[i*2].step=b[i*2+1].step=0; b[i*2].sum=(b[i*2].r-b[i*2].l+1)*b[i*2].v; b[i*2+1].sum=(b[i*2+1].r-b[i*2+1].l+1)*b[i*2+1].v; b[i].flag=-1; } if(b[i].add1 || b[i].add2 || b[i].step){ add1=b[i].add1; add2=b[i].add1+b[i].step*(mid-b[i].l); add3=add2+b[i].step; add4=b[i].add2; b[i*2].add1+=add1;b[i*2].add2+=add2; b[i*2+1].add1+=add3;b[i*2+1].add2+=add4; b[i*2].sum+=(b[i*2].r-b[i*2].l+1)*(add1+add2)/2; b[i*2+1].sum+=(b[i*2+1].r-b[i*2+1].l+1)*(add3+add4)/2; b[i*2].step+=b[i].step; b[i*2+1].step+=b[i].step; b[i].add1=b[i].add2=b[i].step=0; } } void updateA(ll l,ll r,ll add,ll i) { ll mid,add1,add2; if(b[i].l==l && b[i].r==r){ add1=add;add2=add+b[i].r-b[i].l; b[i].add1+=add1;b[i].add2+=add2; b[i].step+=1;b[i].sum+=(b[i].r-b[i].l+1)*(add2+add1)/2; //b[i].flag=-1;这里注意不能使得b[i].flag=-1,因为对于所有数相同的区间,它的add1,add2可以不为0 return; } pushdown(i); mid=(b[i].l+b[i].r)/2; if(r<=mid)updateA(l,r,add,i*2); else if(l>mid)updateA(l,r,add,i*2+1); else{ updateA(l,mid,add,i*2); updateA(mid+1,r,add+mid+1-l,i*2+1); } b[i].sum=b[i*2].sum+b[i*2+1].sum; } void updateB(ll l,ll r,ll add,ll i) { ll mid,add1,add2; if(b[i].l==l && b[i].r==r){ add1=add+b[i].r-b[i].l;add2=add; b[i].add1+=add1;b[i].add2+=add2; b[i].step-=1;b[i].sum+=(b[i].r-b[i].l+1)*(add2+add1)/2; return; } pushdown(i); mid=(b[i].l+b[i].r)/2; if(r<=mid)updateB(l,r,add,i*2); else if(l>mid)updateB(l,r,add,i*2+1); else{ updateB(l,mid,add+r-mid,i*2); updateB(mid+1,r,add,i*2+1); } b[i].sum=b[i*2].sum+b[i*2+1].sum; } void updateC(ll l,ll r,ll num,ll i) { ll mid; if(b[i].l==l && b[i].r==r){ b[i].add1=b[i].add2=b[i].step=0; b[i].sum=(b[i].r-b[i].l+1)*num; b[i].flag=0; b[i].v=num; return; } pushdown(i); mid=(b[i].l+b[i].r)/2; if(r<=mid)updateC(l,r,num,i*2); else if(l>mid)updateC(l,r,num,i*2+1); else{ updateC(l,mid,num,i*2); updateC(mid+1,r,num,i*2+1); } b[i].sum=b[i*2].sum+b[i*2+1].sum; } void question(ll l,ll r,ll i) { ll mid; if(b[i].l==l && b[i].r==r){ sum+=b[i].sum;return; } pushdown(i); mid=(b[i].l+b[i].r)/2; if(r<=mid) question(l,r,i*2); else if(l>mid) question(l,r,i*2+1); else{question(l,mid,i*2);question(mid+1,r,i*2+1);} } int main() { ll n,m,i,j; while(scanf("%lld",&n)!=EOF) { build(1,250000,1); for(i=1;i<=n;i++){ char s[10]; ll c,d,e; scanf("%s",s); if(s[0]=='A'){ scanf("%lld%lld",&c,&d); updateA(c,d,1,1); } else if(s[0]=='B'){ scanf("%lld%lld",&c,&d); updateB(c,d,1,1); } else if(s[0]=='C'){ scanf("%lld%lld%lld",&c,&d,&e); updateC(c,d,e,1); } else if(s[0]=='S'){ scanf("%lld%lld",&c,&d); sum=0; question(c,d,1); printf("%lld\n",sum); } } } return 0; } /* 10 B 1 4 A 1 4 S 2 2 B 1 3 C 1 4 1 B 1 4 C 3 3 3 A 2 3 S 2 3 B 3 3 */
相关文章推荐
- 一个答案不唯一的数独问题
- UVa439(BFS最短路实现)
- HDU 3023 Dirt 踩黑白块
- mysql服务启动、停止、重启
- 八大排序总结
- UVa439(DFS实现)
- 【数据结构】1、串的模式匹配算法
- 算法学习笔记——贪婪
- SQL基础学习_04_视图
- 命令别名alias设置
- Java 设计模式—装饰者模式
- (_)snprintf跨平台测试
- hdu 5130 && BestCoder 1st Anniversary 1001
- java socket编程
- 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记39 Alert&ActionSheet
- Linux命令学习手册-tr命令
- Java设计模式偷跑系列(21)建模和实现享受metapatterns
- Linux命令学习手册-tr命令 2015-07-26 20:35 9人阅读 评论(0) 收藏
- [BZOJ 1001] [BeiJing2006]狼抓兔子
- UVA 10878