MASTER OF GCD(树状数组差分|线段树)

版权声明:本文为博主原创文章,转载请说明出处。 https://blog.csdn.net/xianpingping/article/details/83151895

嗯。反正这道题当时忘记了树状数组差分。用的线段树。比赛时写这么长的线段树时间上多少有点吃亏。

就是两个树,维护区间加1操作,然后分别查两棵树的最小值。

树状数组差分:

#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+100;
const int mod=998244353;
const int inf=0x3f3f3f3f;
typedef long long LL;
LL sum1[maxn];
LL sum2[maxn];
int n;
LL lowbit(int x){
    return x&(-x);
}
LL add(int x,LL *C,int k){
    while(x<maxn){
        C[x]+=k;
        x+=lowbit(x);
    }
}
LL sum(int x,LL *C){
    LL ans=0;
    while(x>0){
        ans+=C[x];
        x-=lowbit(x);
    }
    return ans;
}
LL powmod(LL a,LL n){
    LL ans=1;
    while(n){
        if(n&1)
            ans=(ans*a)%mod;
        a=(a*a)%mod;
        n>>=1;
    }
    return ans;
}

int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        memset(sum1,0,sizeof(sum1));
        memset(sum2,0,sizeof(sum2));
        for(int i=1;i<=m;i++){
            int l,r,c;
            scanf("%d%d%d",&l,&r,&c);
            if(c==2){
                add(l,sum1,1);
                add(r+1,sum1,-1);
            }
            else{
                add(l,sum2,1);
                add(r+1,sum2,-1);
            }
        }
        LL minn1=inf;
        LL minn2=inf;
        for(int i=1;i<=n;i++){
            minn1=min(minn1,sum(i,sum1));
            minn2=min(minn2,sum(i,sum2));
        }
        minn1=powmod(2,minn1);
        minn2=powmod(3,minn2);
        cout<<(minn1*minn2)%mod<<endl;
    }
    return 0;
}
/*
2
5 3
1 3 2
3 5 2
1 5 3

6 3
1 2 2
5 6 2
1 6 2

*/

比赛时写的线段树:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l,mid,id*2
#define rson mid+1,r,id*2+1
typedef long long LL;
const int inf=0x3f3f3f3f;
const int modif=998244353;
const int maxn=100000+100;
LL sum2[maxn<<2];
///LL minn2[maxn<<2];
LL lazy2[maxn<<2];


LL sum3[maxn<<2];
///LL minn3[maxn<<2];
LL lazy3[maxn<<2];

void pushdown3(LL id,LL m){
    if(lazy3[id]){
        lazy3[id*2]+=lazy3[id];
        lazy3[id*2+1]+=lazy3[id];

        sum3[id*2]+=lazy3[id];
        sum3[id*2+1]+=lazy3[id];
        lazy3[id]=0;///标记root状态已更新
    }
}
void pushup3(LL id){
    sum3[id]=min(sum3[id*2],sum3[id*2+1]);
    lazy3[id]=0;
}
void update3(LL l,LL r,LL id,LL L,LL R,LL w){
    if(l>=L && r<=R)
    {
        lazy3[id]+=w;///标志当前这段区间更新了,但是这段区间下边的还没有更新
        sum3[id]=sum3[id]+w;
        return ;
    }
    pushdown3(id,r-l+1);///如果这次更新过程中有靠下的,就会一直更新,下放
    LL mid=(l+r)/2;
    if(L<=mid){
        update3(lson,L,R,w);
    }
    if(R>mid){
        update3(rson,L,R,w);
    }
    pushup3(id);
}
LL query3(LL l,LL r,LL id,LL L,LL R){
    LL ans=inf;
    if(l>=L &&r<=R){
        return sum3[id];
    }
    pushdown3(id,r-l+1);///查的时候遇到靠下的也要一直下放
    LL mid=(l+r)/2;
    if(L<=mid){
        ans=min(ans,query3(lson,L,R));
    }
    if(R>mid){
        ans=min(ans,query3(rson,L,R));
    }
    pushup3(id);
    return ans;
}



void pushdown2(LL id,LL m){
    if(lazy2[id]){
        lazy2[id*2]+=lazy2[id];
        lazy2[id*2+1]+=lazy2[id];

        sum2[id*2]+=lazy2[id];
        sum2[id*2+1]+=lazy2[id];
        lazy2[id]=0;///标记root状态已更新
    }
}
void pushup2(LL id){
    sum2[id]=min(sum2[id*2],sum2[id*2+1]);
    lazy2[id]=0;
}
void update2(LL l,LL r,LL id,LL L,LL R,LL w){
    if(l>=L && r<=R)
    {
        lazy2[id]+=w;///标志当前这段区间更新了,但是这段区间下边的还没有更新
        sum2[id]=sum2[id]+w;
        return ;
    }
    pushdown2(id,r-l+1);///如果这次更新过程中有靠下的,就会一直更新,下放
    LL mid=(l+r)/2;
    if(L<=mid){
        update2(lson,L,R,w);
    }
    if(R>mid){
        update2(rson,L,R,w);
    }
    pushup2(id);
}
LL query2(LL l,LL r,LL id,LL L,LL R){
    LL ans=inf;
    if(l>=L &&r<=R){
        return sum2[id];
    }
    pushdown2(id,r-l+1);///查的时候遇到靠下的也要一直下放
    LL mid=(l+r)/2;
   /// LL ans=inf;
    if(L<=mid){
        ans=min(ans,query2(lson,L,R));
    }
    if(R>mid){
        ans=min(ans,query2(rson,L,R));
    }
    pushup2(id);
    return ans;
}




int main()
{
    int t,n,m,aa,bb,cc;
    scanf("%d",&t);
    while(t--){
        memset(sum2,0,sizeof(sum2));
     memset(lazy3,0,sizeof(lazy3));
        memset(sum3,0,sizeof(sum3));
       memset(lazy2,0,sizeof(lazy2));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&aa,&bb,&cc);
            if(cc==2)
                update2(1,n,1,aa,bb,1);
            else
                update3(1,n,1,aa,bb,1);
        }
        LL lala2=query2(1,n,1,1,n);
        LL lala3=query3(1,n,1,1,n);
        LL res=1;
        //cout<<lala2<<"  "<<lala3<<endl;
        if(lala2>0)
        {
            for(int i=0;i<lala2;i++)
                res=(res*2)%modif;
        }
        if(lala3>0)
        {
            for(int i=0;i<lala3;i++)
                res=(res*3)%modif;
        }
        //cout<<res2<<" "<<res3<<endl;
        cout<<res<<endl;
    }

}

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/83151895
今日推荐