CDOJ 1259 昊昊爱运动 II 线段树+bitset

昊昊爱运动 II

昊昊喜欢运动

N天内会参加M种运动(每种运动用一个[1,m]的整数表示)

现在有Q个操作,操作描述如下

  • 昊昊把第l天到第r天的运动全部换成了x(x[1,m])
  • 问昊昊第l天到第r天参加了多少种不同的运动

Input

输入两个数NM (1N1051M100);

输入N个数ai(ai[1,m])表示在第i天昊昊做了第ai类型的运动;

输入一个数Q(1Q105);

输入Q行 每行描述以下两种操作

  • 形如M l r x,表示昊昊把第l天到第r天的运动全部换成了x(x[1,m])
  • 形如Q l r,表示昊昊想知道他第l天到第r天参加了多少种不同的运动

Output

对于所有的Q操作,每一行输出一个数 表示昊昊在第l天到第r天一共做了多少种活动

Sample input and output

Sample InputSample Output
5 3
1 2 3 2 3
4
Q 1 4
Q 2 4
M 5 5 2
Q 1 5
3
2
3

Source

题解:线段树+bitset

//meek///#include<bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<bitset>
using namespace std ;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
#define fi first
#define se second
#define MP make_pair
typedef long long ll;

const int maxn = 100005;
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
bitset<101> ret;
int a[maxn];
struct ss {
  int l,r;
  int tag;
  bitset<101> b;
}tr[maxn << 2];
void pushup(int k) {
     tr[k].b=tr[k<<1].b | tr[k<<1|1].b;
}
void pushdown(int k) {
    if(!tr[k].tag||tr[k].l==tr[k].r) return ;
    tr[k<<1].tag=tr[k].tag;
    tr[k<<1|1].tag=tr[k].tag;
    tr[k<<1].b.reset();tr[k<<1].b.set(tr[k].tag);
    tr[k<<1|1].b.reset();tr[k<<1|1].b.set(tr[k].tag);
    tr[k].tag=0;
}
void build(int k,int s,int t) {
    tr[k].l=s;tr[k].r=t;
    tr[k].b.reset();
    tr[k].tag=0;
    if(s==t) {
        tr[k].b.set(a[s]);
        return ;
    }
    int mid = (s+t) >> 1;
    build(k<<1,s,mid);build(k<<1|1,mid+1,t);
    pushup(k);
}
void modify(int k,int s,int t,int c) {
     pushdown(k);
     if(s==tr[k].l&&t==tr[k].r) {
        tr[k].b.reset();
        tr[k].tag=c;
        tr[k].b.set(c);
        return ;
     }
     int mid = (tr[k].l+tr[k].r) >> 1;
     if(t<=mid) modify(k<<1,s,t,c);
     else if(s>mid) modify(k<<1|1,s,t,c);
     else {
        modify(k<<1,s,mid,c);
        modify(k<<1|1,mid+1,t,c);
     }
     pushup(k);
}
void ask(int k,int s,int t) {
    pushdown(k);
    if(s==tr[k].l&&t==tr[k].r) {
        ret|=tr[k].b;
        return ;
    }
    int mid = (tr[k].l+tr[k].r) >> 1;
    if(t<=mid) ask(k<<1,s,t);
     else if(s>mid) ask(k<<1|1,s,t);
     else {
        ask(k<<1,s,mid);
        ask(k<<1|1,mid+1,t);
     }
}
int main() {
    int n,m,l,r,x,q;char ch[20];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)   scanf("%d",&a[i]);
    build(1,1,n);
    scanf("%d",&q);
    for(int i=1;i<=q;i++) {
        scanf("%s",ch);
        if(ch[0]=='Q') {
            scanf("%d%d",&l,&r);
            ret.reset();ask(1,l,r);
            printf("%d
",ret.count());
        }
        else {
            scanf("%d%d%d",&l,&r,&x);
            modify(1,l,r,x);
        }
    }
    return 0;
}
代码
 
原文地址:https://www.cnblogs.com/zxhl/p/5052255.html