您的位置:首页 > 运维架构

bzoj 维护序列seq(双标记线段树)

2016-03-24 12:35 316 查看

Seq 维护序列seq

Time Limit: 30 Sec Memory Limit: 64 MB
Submit: 4184 Solved: 1518
[Submit][Status][Discuss]

Description

老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成。 有长为N的数列,不妨设为a1,a2,…,aN 。有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列中的一段数全部加一个值; (3)询问数列中的一段数的和,由于答案可能很大,你只需输出这个数模P的值。

Input

第一行两个整数N和P(1≤P≤1000000000)。第二行含有N个非负整数,从左到右依次为a1,a2,…,aN, (0≤ai≤1000000000,1≤i≤N)。第三行有一个整数M,表示操作总数。从第四行开始每行描述一个操作,输入的操作有以下三种形式: 操作1:“1 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai×c (1≤t≤g≤N,0≤c≤1000000000)。 操作2:“2 t g c”(不含双引号)。表示把所有满足t≤i≤g的ai改为ai+c (1≤t≤g≤N,0≤c≤1000000000)。 操作3:“3 t g”(不含双引号)。询问所有满足t≤i≤g的ai的和模P的值 (1≤t≤g≤N)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

Output

对每个操作3,按照它在输入中出现的顺序,依次输出一行一个整数表示询问结果。

Sample Input

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

Sample Output

2
35
8

HINT

【样例说明】

初始时数列为(1,2,3,4,5,6,7)。
经过第1次操作后,数列为(1,10,15,20,25,6,7)。
对第2次操作,和为10+15+20=45,模43的结果是2。
经过第3次操作后,数列为(1,10,24,29,34,15,16}
对第4次操作,和为1+10+24=35,模43的结果是35。
对第5次操作,和为29+34+15+16=94,模43的结果是8。

测试数据规模如下表所示

数据编号 1 2 3 4 5 6 7 8 9 10
N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

题解:给两个操作,操作1,把l,r数字乘以c,操作2:把l,r数字都加上c;
直接开两个标记去存储,样例过了,但是无限wa;
我有几点没考虑完全:
1:对于第一个操作,每次标记应该都是乘以c;而我弄成加了,因为假设第一次乘以5,第二次再乘以5,就是25
了;
2:对于第二种操作,没有考虑到第一种操作可以影响第二种操作,如果执行第一种操作,里面的元素编程5倍了,此时标记2也应当乘以相应倍数;加上5+2,5乘以5了,2也应当乘以5;
总结:考虑问题还是不太全面,不能完全驾驭题目;
代码:

extern "C++"{
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cassert>
#include<cstdlib>
using namespace  std;
typedef long long LL;
typedef unsigned u;
typedef unsigned long long ull;
#define mem(x,y) memset(x,y,sizeof(x))
void SI(double &x){scanf("%lf",&x);}
void SI(int &x){scanf("%d",&x);}
void SI(LL &x){scanf("%lld",&x);}
void SI(u &x){scanf("%u",&x);}
void SI(ull &x){scanf("%llu",&x);}
void SI(char *s){scanf("%s",s);}

void PI(int x){printf("%d",x);}
void PI(double x){printf("%lf",x);}
void PI(LL x){printf("%lld",x);}
void PI(u x){printf("%u",x);}
void PI(ull x){printf("%llu",x);}
void PI(char *s){printf("%s",s);}

#define NL puts("");
#define ll root<<1
#define rr root<<1|1
#define lson ll,l,mid
#define rson rr,mid+1,r
const int INF=0x3f3f3f3f;
const int MAXN=100010;
LL tree[MAXN << 2];
LL lazy[MAXN << 2];
LL lazy2[MAXN << 2];
LL P;
}
void pushup(int root){
tree[root] = tree[ll] + tree[rr];
tree[root] %= P;
}
void pushdown(int root,int x){
if(lazy[root] != 1){
lazy[ll] *= lazy[root];
lazy[rr] *= lazy[root];

lazy2[ll] *= lazy[root];
lazy2[rr] *= lazy[root];
//    tree[ll]=lazy[root]*(mid-l+1);
//    tree[rr]=lazy[root]*(r-mid);
tree[ll] *= lazy[root];
tree[rr] *= lazy[root];

lazy[ll] %= P;
lazy[rr] %= P;
tree[ll] %= P;
tree[rr] %= P;
lazy2[ll] %= P;
lazy2[rr] %= P;

lazy[root] = 1;
}
if(lazy2[root]){
lazy2[ll] += lazy2[root];
lazy2[rr] += lazy2[root];

lazy2[ll] %= P;
lazy2[rr] %= P;

tree[ll] += lazy2[root] * (x - (x >> 1) ) % P;
tree[rr] += lazy2[root] * (x >> 1) % P;

tree[ll] %= P;
tree[rr] %= P;

lazy2[root] = 0;
}
}
void build(int root,int l,int r){
int mid = (l + r) >> 1;
lazy[root] = 1;
lazy2[root] = 0;
if(l == r){
SI(tree[root]);
return ;
}
build(lson);
build(rson);
pushup(root);
}
void update(int root,int l,int r,int L,int R,int C,int t){
if(l >= L && r <= R){
if(t == 1){
lazy[root] *= C;
tree[root] *= C;
lazy2[root] *= C;
lazy2[root] %= P;
lazy[root] %= P;
tree[root] %= P;
}
else if(t == 2){
lazy2[root] += C % P;
tree[root] += C * (r - l +1) % P;
lazy2[root] %= P;
tree[root] %= P;
}
return ;
}
int mid = (l + r) >> 1;
pushdown(root,r - l + 1);
if(mid >= L)
update(lson,L,R,C,t);
if(mid < R)
update(rson,L,R,C,t);
pushup(root);
}
LL query(int root,int l,int r,int L,int R){
int mid = (l + r) >> 1;
if(l >= L && r <= R){
return tree[root];
}
pushdown(root,r - l + 1);
LL ans = 0;
if(mid >= L)
ans += query(lson,L,R);
if(mid < R)
ans += query(rson,L,R);
return ans;
}
int main(){
//    assert(true);
int N,M;
while(~scanf("%d%lld",&N,&P)){
build(1,1,N);
SI(M);
int a,l,r,c;
while(M--){
SI(a);SI(l);SI(r);
if(a == 3){
printf("%lld\n",query(1,1,N,l,r) % P);
}
else{
SI(c);
update(1,1,N,l,r,c,a);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: