http://acm.hdu.edu.cn/showproblem.php?pid=4578
N个数,4种操作。
1.
2.
3.
4. 询问区间
之前做线段树一直很不6,今天自己把这几个维护的式子推了一遍,终于找到点感觉了。
询问的p只有123,分别维护好就行了。操作3等价于乘0再加c。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MID int mid = (L+R)>>1;
#define CHD int lc = node<<1, rc = node<<1|1;
#define rep(i,f,t) for(int i = f; i <= t; ++i)
int n,m;
typedef long long int64;
const int maxn = 100001<<2;
const int mod = 10007;
struct sgt{
int64 sum[maxn][4];
int64 addv[maxn];
int64 mulv[maxn];
void init(){ addv[1] = mulv[1] = 0; }
int tp,v;
void pushDown(int node){
CHD;
if(mulv[node] != 1){
mulv[lc] = mulv[lc] * mulv[node] % mod;
mulv[rc] = mulv[rc] * mulv[node] % mod;
addv[lc] = addv[lc] * mulv[node] % mod;
addv[rc] = addv[rc] * mulv[node] % mod;
}
if(addv[node] != 0){
addv[lc] = (addv[lc] + addv[node]) % mod;
addv[rc] = (addv[rc] + addv[node]) % mod;
}
mulv[node] = 1;
addv[node] = 0;
}
void maintain(int node,int L,int R){
CHD;
if(L != R)
rep(i,1,3) sum[node][i] = (sum[lc][i] + sum[rc][i]) % mod;
if(mulv[node] == 0){
rep(i,1,3)sum[node][i] = 0;
}else if(mulv[node] != 1){
sum[node][1] = sum[node][1]*mulv[node]%mod;
sum[node][2] = sum[node][2]*mulv[node]*mulv[node]%mod;
sum[node][3] = sum[node][3]*mulv[node]*mulv[node]*mulv[node]%mod;
}
if(addv[node]){
//这三个顺序不能反
sum[node][3] = ( sum[node][3] + addv[node]*sum[node][2]*3%mod
+ addv[node]*addv[node]*sum[node][1]*3%mod
+ addv[node]*addv[node]*addv[node]%mod*(R-L+1)%mod) % mod;
sum[node][2] = ( sum[node][2] + addv[node]*sum[node][1]*2%mod
+ addv[node]*addv[node]*(R-L+1)%mod) % mod;
sum[node][1] = ( sum[node][1] + addv[node]*(R-L+1) ) % mod;
}
//叶子结点,可以把标记清除
if(L == R){
mulv[node] = 1;
addv[node] = 0;
}
}
void update(int from,int to,int val,int node,int L,int R){
if(from <= L && R <= to){
if(tp == 1){
addv[node] = (addv[node] + val) % mod;
} else if(tp == 2){
addv[node] = (addv[node] * val) % mod;
mulv[node] = (mulv[node] * val) % mod;
} else {
addv[node] = val;
mulv[node] = 0;
}
maintain(node,L,R);
return;
}
pushDown(node);
MID;CHD;
if(from <= mid) update(from,to,val,lc,L,mid);
else maintain(lc,L,mid);
if(to > mid) update(from,to,val,rc,mid+1,R);
else maintain(rc,mid+1,R);
maintain(node,L,R);
}
int query(int from,int to,int node,int L,int R){
maintain(node,L,R);
if(from <= L && R <= to){
return sum[node][v];
}
int ans = 0;
pushDown(node);
MID;CHD;
if(from <= mid) ans += query(from,to,lc,L,mid);
else maintain(lc,L,mid);
if(to > mid) ans += query(from,to,rc,mid+1,R);
else maintain(rc,mid+1,R);
return ans%mod;
}
void run(){
while(m--){
int f,t;
scanf("%d%d%d%d",&tp,&f,&t,&v);
if(tp == 4){
int ans = query(f,t,1,1,n);
printf("%d
",ans);
} else {
update(f,t,v,1,1,n);
}
}
}
}tree;
int main(){
while(scanf("%d%d",&n,&m), n||m){
tree.init();
tree.run();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。