K - Transformation

思路:发现自己的错误竟然是zz般的少了一个取模   ε=ε=ε=(#>д<)ノ
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define p 10007
#define MAXN 100010
using namespace std;
int n,m;
struct nond{
    int l,r;
    int sum[4];
    int flag1,flag2,flag3;
}tree[MAXN*4];
void up(int now){
    tree[now].sum[1]=(tree[now*2].sum[1]+tree[now*2+1].sum[1])%p;
    tree[now].sum[2]=(tree[now*2].sum[2]+tree[now*2+1].sum[2])%p;
    tree[now].sum[3]=(tree[now*2].sum[3]+tree[now*2+1].sum[3])%p;
}
void build(int now,int l,int r){
    tree[now].l=l;tree[now].r=r;
    tree[now].sum[1]=0;tree[now].sum[2]=0;
    tree[now].sum[3]=0;tree[now].flag2=1;
    tree[now].flag1=tree[now].flag3=0;
    if(tree[now].l==tree[now].r)    return ;
    int mid=(tree[now].l+tree[now].r)/2;
    build(now*2,l,mid);
    build(now*2+1,mid+1,r);
    up(now);
}
void down(int now){
    if(tree[now].flag3){
        tree[now*2].sum[1]=(((tree[now*2].r-tree[now*2].l+1)%p)*tree[now].flag3)%p;
        tree[now*2].sum[2]=(((((tree[now*2].r-tree[now*2].l+1)%p)*tree[now].flag3)%p)*tree[now].flag3)%p;
        tree[now*2].sum[3]=(((((((tree[now*2].r-tree[now*2].l+1)%p)*tree[now].flag3)%p)*tree[now].flag3)%p)*tree[now].flag3)%p;
        tree[now*2].flag3=tree[now].flag3%p;
        tree[now*2].flag1=0;tree[now*2].flag2=1;
        
        tree[now*2+1].sum[1]=(((tree[now*2+1].r-tree[now*2+1].l+1)%p)*tree[now].flag3)%p;
        tree[now*2+1].sum[2]=(((((tree[now*2+1].r-tree[now*2+1].l+1)%p)*tree[now].flag3)%p)*tree[now].flag3)%p;
        tree[now*2+1].sum[3]=(((((((tree[now*2+1].r-tree[now*2+1].l+1)%p)*tree[now].flag3)%p)*tree[now].flag3)%p)*tree[now].flag3)%p;
        tree[now*2+1].flag3=tree[now].flag3%p;
        tree[now*2+1].flag1=0;tree[now*2+1].flag2=1;
        
        tree[now].flag3=0;
    }
    if(tree[now].flag2){
        tree[now*2].sum[3]=(((((tree[now*2].sum[3]*tree[now].flag2)%p)*tree[now].flag2)%p)*tree[now].flag2)%p;
        tree[now*2].sum[2]=(((tree[now*2].sum[2]*tree[now].flag2)%p)*tree[now].flag2)%p;
        tree[now*2].sum[1]=(tree[now*2].sum[1]*tree[now].flag2)%p;
        tree[now*2].flag1=(tree[now*2].flag1*tree[now].flag2)%p;
        tree[now*2].flag2=(tree[now*2].flag2*tree[now].flag2)%p;
        
        tree[now*2+1].sum[3]=(((((tree[now*2+1].sum[3]*tree[now].flag2)%p)*tree[now].flag2)%p)*tree[now].flag2)%p;
        tree[now*2+1].sum[2]=(((tree[now*2+1].sum[2]*tree[now].flag2)%p)*tree[now].flag2)%p;
        tree[now*2+1].sum[1]=(tree[now*2+1].sum[1]*tree[now].flag2)%p;
        tree[now*2+1].flag1=(tree[now*2+1].flag1*tree[now].flag2)%p;
        tree[now*2+1].flag2=(tree[now*2+1].flag2*tree[now].flag2)%p;
        
        tree[now].flag2=1;
    }
    if(tree[now].flag1){
        tree[now*2].sum[3]=(tree[now*2].sum[3]+(((3*tree[now].flag1*tree[now].flag1%p*tree[now*2].sum[1])%p+(3*tree[now].flag1*tree[now*2].sum[2])%p)%p+(tree[now*2].r-tree[now*2].l+1)%p*tree[now].flag1%p*tree[now].flag1%p*tree[now].flag1)%p)%p;  
        tree[now*2].sum[2]=(tree[now*2].sum[2]+((tree[now*2].r-tree[now*2].l+1)%p*tree[now].flag1%p*tree[now].flag1%p+(2*tree[now].flag1*tree[now*2].sum[1])%p)%p)%p;  
        tree[now*2].sum[1]=(tree[now*2].sum[1]+(tree[now*2].r-tree[now*2].l+1)%p*tree[now].flag1)%p;
        tree[now*2].flag1=(tree[now*2].flag1+tree[now].flag1)%p;
        
        tree[now*2+1].sum[3]=(tree[now*2+1].sum[3]+(((3*tree[now].flag1*tree[now].flag1%p*tree[now*2+1].sum[1])%p+(3*tree[now].flag1*tree[now*2+1].sum[2])%p)%p+(tree[now*2+1].r-tree[now*2+1].l+1)%p*tree[now].flag1%p*tree[now].flag1%p*tree[now].flag1)%p)%p;  
        tree[now*2+1].sum[2]=(tree[now*2+1].sum[2]+((tree[now*2+1].r-tree[now*2+1].l+1)%p*tree[now].flag1%p*tree[now].flag1%p+(2*tree[now].flag1*tree[now*2+1].sum[1])%p)%p)%p;  
        tree[now*2+1].sum[1]=(tree[now*2+1].sum[1]+(tree[now*2+1].r-tree[now*2+1].l+1)%p*tree[now].flag1)%p;
        tree[now*2+1].flag1=(tree[now*2+1].flag1+tree[now].flag1)%p;
        
        tree[now].flag1=0;
    }
}
void changeadd(int now,int l,int r,int k){
     if(tree[now].l==l&&tree[now].r==r){
        tree[now].sum[3]=(tree[now].sum[3]+(((3*k*k%p*tree[now].sum[1])%p+(3*k*tree[now].sum[2])%p)%p+(tree[now].r-tree[now].l+1)%p*k%p*k%p*k)%p)%p;  
        tree[now].sum[2]=(tree[now].sum[2]+(((((tree[now].r-tree[now].l+1)%p)*k)%p*k)%p+(2*k*tree[now].sum[1])%p)%p)%p;  
        tree[now].sum[1]=(tree[now].sum[1]+(tree[now].r-tree[now].l+1)%p*k)%p;
        tree[now].flag1=(tree[now].flag1+k)%p;
        return ;
    }
    if(tree[now].flag1||tree[now].flag2!=1||tree[now].flag3)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    changeadd(now*2,l,r,k);
    else if(l>mid)    changeadd(now*2+1,l,r,k);
    else { changeadd(now*2,l,mid,k); changeadd(now*2+1,mid+1,r,k); }
    up(now);
}
void changemul(int now,int l,int r,int k){
    if(tree[now].l==l&&tree[now].r==r){
        tree[now].sum[3]=(((((tree[now].sum[3]*k)%p)*k)%p)*k)%p;
        tree[now].sum[2]=(((tree[now].sum[2]*k)%p)*k)%p;
        tree[now].sum[1]=(tree[now].sum[1]*k)%p;
        tree[now].flag1=(tree[now].flag1*k)%p;
        tree[now].flag2=(tree[now].flag2*k)%p;
        return ;
    }
    if(tree[now].flag1||tree[now].flag2!=1||tree[now].flag3)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    changemul(now*2,l,r,k);
    else if(l>mid)    changemul(now*2+1,l,r,k);
    else{ changemul(now*2,l,mid,k); changemul(now*2+1,mid+1,r,k); }
    up(now);
}
void change(int now,int l,int r,int k){
    if(tree[now].l==l&&tree[now].r==r){
        tree[now].sum[1]=(((tree[now].r-tree[now].l+1)%p)*k)%p;
        tree[now].sum[2]=(((((tree[now].r-tree[now].l+1)%p)*k)%p)*k)%p;
        tree[now].sum[3]=(((((((tree[now].r-tree[now].l+1)%p)*k)%p)*k)%p)*k)%p;
        tree[now].flag3=k%p;
        tree[now].flag1=0;tree[now].flag2=1; 
        return ;
    }
    if(tree[now].flag1||tree[now].flag2!=1||tree[now].flag3)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    change(now*2,l,r,k);
    else if(l>mid)    change(now*2+1,l,r,k);
    else{ change(now*2,l,mid,k); change(now*2+1,mid+1,r,k); }
    up(now);
}
int query(int now,int l,int r,int k){
    if(tree[now].l==l&&tree[now].r==r)
        return tree[now].sum[k];
    if(tree[now].flag1||tree[now].flag2!=1||tree[now].flag3)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    return query(now*2,l,r,k);
    else if(l>mid)    return query(now*2+1,l,r,k);
    else return (query(now*2,l,mid,k)+query(now*2+1,mid+1,r,k))%p;
}
int main(){
    while(scanf("%d%d",&n,&m)&&n!=0&&m!=0){
        build(1,1,n);
        for(int i=1;i<=m;i++){
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if(a==1)    changeadd(1,b,c,d);
            if(a==2)    changemul(1,b,c,d);
            if(a==3)    change(1,b,c,d);
            if(a==4)    printf("%d\n",query(1,b,c,d));
        }
    }
}

 

转载于:https://www.cnblogs.com/cangT-Tlan/p/8470857.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值