萌新求助卡常

学术版

Spasmodic @ 2020-10-30 22:19:50

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100005;
int n,k,m;
struct seg{
    int sum[N<<2],tag[N<<2];
    seg(){memset(tag,-1,sizeof(tag));}
    void pushup(int k){sum[k]=sum[k<<1]+sum[k<<1|1];}
    void lazy(int k,int l,int r,int v){
        tag[k]=v;
        sum[k]=v*(r-l+1);
    }
    void pushdown(int k,int l,int r,int mid){
        if(tag[k]==-1)return;
        lazy(k<<1,l,mid,tag[k]);
        lazy(k<<1|1,mid+1,r,tag[k]);
        tag[k]=-1;
    }
    void modify(int k,int l,int r,int x,int y,int v){
        if(x<=l&&r<=y){
            lazy(k,l,r,v);
            return;
        }
        int mid=l+r>>1;
        pushdown(k,l,r,mid);
        if(x<=mid)modify(k<<1,l,mid,x,y,v);
        if(mid<y)modify(k<<1|1,mid+1,r,x,y,v);
        pushup(k);
    }
    int query(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y)return sum[k];
        int mid=l+r>>1,ret=0;
        pushdown(k,l,r,mid);
        if(x<=mid)ret+=query(k<<1,l,mid,x,y);
        if(mid<y)ret+=query(k<<1|1,mid+1,r,x,y);
        return ret;
    }
}s[31];
char op[2];
int main(){
    scanf("%d%d%d",&n,&k,&m);
    s[1].modify(1,1,n,1,n,1);
    for(int a,b,c;m--;){
        scanf("%s%d%d",op,&a,&b);
        if(a>b)swap(a,b);
        if(op[0]=='C'){
            scanf("%d",&c);
            for(int i=1;i<=k;i++)s[i].modify(1,1,n,a,b,i==c);
        }else{
            int ans=0;
            for(int i=1;i<=k;i++)ans+=(s[i].query(1,1,n,a,b)>0);
            printf("%d\n",ans);
        }
    }
    return 0;
}

当然如果可以解决这个贴的问题就更好


by Spasmodic @ 2020-10-30 22:20:03

无 O2,无 pragma


by ez_lcw @ 2020-10-30 22:21:06

去封装(


by Spasmodic @ 2020-10-30 22:21:10

禁wyy


by Spasmodic @ 2020-10-30 22:22:09

@ez_lcw 感觉主要问题是线段树 4 的常数一乘立刻 2\times 10^8 计算量


by ez_lcw @ 2020-10-30 22:23:19

最好再记一个 bool 型的 tag 数组而不是一开始 memset 31棵线段树?


by Spasmodic @ 2020-10-30 22:23:53

@ez_lcw 然而有 3 个值,0,-1,1


by Spasmodic @ 2020-10-30 22:24:31

哦我好像知道了 我试试


by ez_lcw @ 2020-10-30 22:25:39

@happydef 额,我是指记一个新数组


by AsunderSquall @ 2020-10-30 22:26:10

@happydef 不是在刚刚那个贴还说01序列的吗搞得我还以为可以用位运算


by Spasmodic @ 2020-10-30 22:26:46

然而还是 T……

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100005;
int n,k,m;
struct seg{
    int sum[N<<2];
    bool tag1[N<<2],tag2[N<<2];
    void pushup(int k){sum[k]=sum[k<<1]+sum[k<<1|1];}
    void lazy(int k,int l,int r,int v){
        tag1[k]=v,tag2[k]=1;
        sum[k]=(v==1?r-l+1:0);
    }
    void pushdown(int k,int l,int r,int mid){
        if(!tag2[k])return;
        lazy(k<<1,l,mid,tag1[k]);
        lazy(k<<1|1,mid+1,r,tag1[k]);
        tag2[k]=0;
    }
    void modify(int k,int l,int r,int x,int y,int v){
        if(x<=l&&r<=y){
            lazy(k,l,r,v);
            return;
        }
        int mid=l+r>>1;
        pushdown(k,l,r,mid);
        if(x<=mid)modify(k<<1,l,mid,x,y,v);
        if(mid<y)modify(k<<1|1,mid+1,r,x,y,v);
        pushup(k);
    }
    int query(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y)return sum[k];
        int mid=l+r>>1,ret=0;
        pushdown(k,l,r,mid);
        if(x<=mid)ret+=query(k<<1,l,mid,x,y);
        if(mid<y)ret+=query(k<<1|1,mid+1,r,x,y);
        return ret;
    }
}s[31];
char op[2];
int main(){
    scanf("%d%d%d",&n,&k,&m);
    s[1].lazy(1,1,n,1); 
    for(int a,b,c;m--;){
        scanf("%s%d%d",op,&a,&b);
        if(a>b)swap(a,b);
        if(op[0]=='C'){
            scanf("%d",&c);
            for(int i=1;i<=k;i++)s[i].modify(1,1,n,a,b,i==c);
        }else{
            int ans=0;
            for(int i=1;i<=k;i++)ans+=(s[i].query(1,1,n,a,b)>0);
            printf("%d\n",ans);
        }
    }
    return 0;
}

| 下一页