CF上给的标签是数据结构。但给的题解里的方法是很巧的暴力,用vector<set>维护每个字母出现的下标,每次修改加下标,擦下标。每次询问对每个字母分别lower_bound查找区间内是否存在这样位置,实在太妙了!

先看题解的方法。

 #include <bits/stdc++.h>
#define debug(x) cout << #x << ": " << x << endl
using namespace std;
typedef long long ll;
const int MAXN=2e5+;
const int INF=0x3f3f3f3f; int main()
{
ios::sync_with_stdio(false);
cin.tie();
string s;
cin>>s;
vector<set<int> > alp();
for(int i=;i<s.size();++i)
{
alp[s[i] - 'a'].insert(i);
}
int q;
cin>>q;
while(q--)
{
int op;
cin>>op;
if(op==)
{
int pos;
char c;
cin>>pos>>c;
--pos;
alp[s[pos]-'a'].erase(pos);
s[pos]=c;
alp[s[pos]-'a'].insert(pos);
}
else
{
int l,r;
cin>>l>>r;
--l,--r;
int cnt=;
for(int i=;i<;++i)
{
auto k=alp[i].lower_bound(l);
if(k!=alp[i].end() && *k<=r) cnt++;
}
cout<<cnt<<endl;
}
}
return ;
}

然而我看别人线段树的代码没看懂。

但巧了我又去补了道 POJ - 2777

立马发现这两题有异曲同工之处。

POJ的题意是给线段染色,起始一种颜色,区间染色,最多30种颜色,询问区间中有几种颜色。应该是用了bitmask,用不同的位代表不同的颜色,每位上1代表存在这样的颜色,最后对所询问区间内按位或,再统计几位为1就为答案。

还要求你支持区间修改,这CF上这题只有要求单点更新的,很显然我们也可以用不同的位上的1代表不同的字母,最后将区间内的值按位或即可,最后统计有几位为1,就是这个区间几个不同的字母。

下见代码该题线段树解法。

 #include <iostream>
#define debug(x) cout << #x << ": " << x << endl
#define lson (rt<<1)
#define rson (rt<<1|1)
#define Lson l,m,lson
#define Rson m+1,r,rson
using namespace std;
typedef long long ll;
const int MAXN=1e5+;
const int INF=0x3f3f3f3f;
int seg[MAXN<<],lazy[MAXN<<];
string s; inline void pushup(int rt){seg[rt]=(seg[lson]|seg[rson]);} void pushdown(int rt)
{
if(lazy[rt])
{
seg[lson]=seg[rson]=lazy[rt];
lazy[lson]=lazy[rson]=lazy[rt];
lazy[rt]=;
}
} void build(int rt,int l,int r)
{
if(l==r) {seg[rt]=<<(s[l-]-'a');return;}
int mid=l+r>>;
build(lson,l,mid);
build(rson,mid+,r);
pushup(rt);
} void update(int rt,int l,int r,int L,int R,int item)
{
if(l>=L && r<=R) {seg[rt]=<<item;lazy[rt]=<<item;return;}
int mid=l+r>>;
pushdown(rt);
if(L<=mid) update(lson,l,mid,L,R,item);
if(R>mid) update(rson,mid+,r,L,R,item);
pushup(rt);
} int query(int rt,int l,int r,int L,int R)
{
if(l>=L && r<=R){return seg[rt];}
int mid=l+r>>;
pushdown(rt);
int ans1=,ans2=,ans=;
if(L<=mid) ans1=query(lson,l,mid,L,R);
if(R>mid) ans2=query(rson,mid+,r,L,R);
ans=ans1|ans2;
return ans; }
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int q;
cin>>s>>q;
int n=s.size();
build(,,n);
while(q--)
{
int op;
cin>>op;
if(op==)
{
int p;
string z;
cin>>p>>z;
int x=z[]-'a';
update(,,n,p,p,x);
}
else if(op==)
{
int L,R;
cin>>L>>R;
int cnt=,ans=query(,,n,L,R);
while(ans)
{
if(ans&) cnt++;
ans>>=;
}
cout<<cnt<<endl;
}
}
return ;
}

Codeforces Round #590 D. Distinct Characters Queries的更多相关文章

  1. Codeforces Round #590

    题目链接:Round #590 题目答案:官方Editorial.My Solution A. Equalize Prices Again 签到题还WA了一发,向上取整有点问题: //my wrong ...

  2. Codeforces Round #590 (Div. 3)

    A. Equalize Prices Again 题目链接:https://codeforces.com/contest/1234/problem/A 题意:给你 n 个数 , 你需要改变这些数使得这 ...

  3. Codeforces Round #590 (Div. 3)(e、f待补

    https://codeforces.com/contest/1234/problem/A A. Equalize Prices Again #include<bits/stdc++.h> ...

  4. Codeforces Round #590 (Div. 3) Editorial

    Codeforces Round #590 (Div. 3) Editorial 题目链接 官方题解 不要因为走得太远,就忘记为什么出发! Problem A 题目大意:商店有n件商品,每件商品有不同 ...

  5. Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)

    链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...

  6. Codeforces Round #590 (Div. 3) C. Pipes

    链接: https://codeforces.com/contest/1234/problem/C 题意: You are given a system of pipes. It consists o ...

  7. Codeforces Round #590 (Div. 3) A. Equalize Prices Again

    链接: https://codeforces.com/contest/1234/problem/A 题意: You are both a shop keeper and a shop assistan ...

  8. Codeforces Round #590 (Div. 3) E. Special Permutations

    链接: https://codeforces.com/contest/1234/problem/E 题意: Let's define pi(n) as the following permutatio ...

  9. Codeforces Round #590 (Div. 3) B2. Social Network (hard version)

    链接: https://codeforces.com/contest/1234/problem/B2 题意: The only difference between easy and hard ver ...

随机推荐

  1. django基础之day08,利用bulk_create 批量插入成千上万条数据

    bulk_create批量插入数据 models.py文件 class Book(models.Model): title=models.CharField(max_length=32) urls.p ...

  2. Caffe源码-Blob类

    Blob类简介 Blob是caffe中的数据传递的一个基本类,网络各层的输入输出数据以及网络层中的可学习参数(learnable parameters,如卷积层的权重和偏置参数)都是Blob类型.Bl ...

  3. [ASP.NET Core 3框架揭秘] 依赖注入[3]:依赖注入模式

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架之中以实现对流程的复用,并按照"好莱坞法则"实现应用程序的代码与框架之间的交互.我们可以采用若干设计模式 ...

  4. Spring基础——IOC九种bean声明方式

    Spring简介 Spring不是服务于开发web项目的功能,或业务.而是服务于项目的开发,方便各层间的解耦调用,方便对类的批量管理,是提高软件开发效率,降低后期维护成本的框架. Spring的核心思 ...

  5. Java面试必看之Integer.parseInt()与Integer.valueOf()

    Integer.parseInt()和Integer.valueOf()都是将成为String转换为Int,但是为什么Java会提供两个这样的方法呢,他们如果是同样的操作,岂不是多此一举? 我们来深挖 ...

  6. Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了

    Redis中几个“看似”高大上的概念,经常有人提到,某些好事者喜欢死扣概念,实战没多少,嘴巴里冒出来的全是高大上的名词,个人一向鄙视概念党,呵呵! 其实这几个概念:缓存穿透/缓存击穿/缓存雪崩,有一个 ...

  7. 管网平差的python程序

    在市政给水管网当中,管网平差的目的是在已知节点流量.管段长度的情况下,求得各管段流量和对应的经济管径.本科生学习阶段了解并掌握管网平差原理及方法是必不可少的环节. 在下面的程序当中,将利用哈代克罗斯法 ...

  8. mongodb-API

    mongodb-API 连接mongo(该操作一般在初始化时就执行) 出现 由于目标计算机积极拒绝,无法连接的错误时 查看是否进行虚拟机的端口转发 将 /etc/ 目录下的mongodb.conf 文 ...

  9. Aiseesoft 4K Converter for Mac如何转换视频格式?Aiseesoft 4K使用方法

    Aiseesoft 4K如何转换视频格式?由于这款4K UHD转换器支持最新的4K编码/解码技术,因此您可以将4K视频转换为4K电视或其他设备支持的任何其他视频格式.Aiseesoft 4K使用方法分 ...

  10. 微信 电脑版 HOOK(WeChat PC Hook)- 定位dll获取数据和调用功能的地址

    方案一:CE搜索内存数据,OD断点查看堆栈方案二:使用旧版本的特征码,在新版本搜索方案三:借鉴WeTool的dll,用ida分析获取地址方案四:ida静态分析微信,看字符串和输出日志 源码: http ...