UESTC-1259 昊昊爱运动 II

昊昊爱运动 II

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 
 

昊昊喜欢运动

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

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

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

Input

输入两个数N, M (1N105, 1M100);

输入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

咦。。。     
 
分析
这道题看上去像是Dynamic len(set(a[LR])),但是单点更新变成了区间更新,看上去不太好搞。
注意到m比较小,可以用更简单的方式来维护,线段树每个结点用bitset保存一下这m个数字的出现情况和更新标记就好了。
 
/*********************************************************
*      --------------Alfheim--------------               *
*   author AbyssalFish                                   *
**********************************************************/
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MAX_N = 1e5+5, MAX_M = 100+28;
int N, M;

int a[MAX_N];

#define para int o = 1, int l = 1, int r = N
#define lo (o<<1)
#define ro (o<<1|1)
#define Tvar int md = (l+r)>>1;
#define lsn lo,l,md
#define rsn ro,md+1,r
#define insd ql <= l && r <= qr
const int ST_SIZE = 1<<18;

int S[ST_SIZE];
bitset<MAX_M> E[ST_SIZE];

inline void sink(int o,int s)
{
    E[o].reset(); E[o].set(S[o] = s);
}

void build(para)
{
    if(l == r){
        E[o].set(a[l]);
    }
    else {
        Tvar
        build(lsn);
        build(rsn);
        E[o] = E[lo] | E[ro];
    }
}



inline void push_down(int o)
{
    if(S[o]){
        sink(lo,S[o]);
        sink(ro,S[o]);
        S[o] = 0;
    }
}

bitset<MAX_M> res;
int ql,qr;
void query(para)
{
    if(insd){
        res |= E[o];
    }
    else {
        push_down(o);
        Tvar
        if(ql <= md) query(lsn);
        if(qr > md) query(rsn);
    }
}

int qval;
void modify(para)
{
    if(insd){
        sink(o,qval);
    }
    else {
        push_down(o);
        Tvar
        if(ql <= md) modify(lsn);
        if(qr > md) modify(rsn);
        E[o] = E[lo] | E[ro];
    }
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("data.txt","r",stdin);
#endif
    scanf("%d%d",&N,&M);
    for(int i = 1; i <= N; i++) scanf("%d",a+i);
    build();
    int Q; scanf("%d",&Q);
    char op[2];
    while(Q--){
        scanf("%s%d%d",op,&ql,&qr);
        if(*op == 'Q'){
            res.reset();
            query();
            printf("%d
", res.count());
        }
        else {
            scanf("%d",&qval);
            modify();
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/5027898.html