码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #590 (Div. 3)

时间:2019-10-02 14:37:51      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:lines   ber   air   cto   letter   ram   namespace   lse   mda   

D. Distinct Characters Queries

Description

You are given a string ss consisting of lowercase Latin letters and qq queries for this string.

Recall that the substring s[l;r]s[l;r] of the string ss is the string slsl+1srslsl+1…sr. For example, the substrings of "codeforces" are "code", "force", "f", "for", but not "coder" and "top".

There are two types of queries:

  • 1 pos c1 pos c (1pos|s|1≤pos≤|s|, cc is lowercase Latin letter): replace sposspos with cc (set spos:=cspos:=c);
  • 2 l r2 l r (1lr|s|1≤l≤r≤|s|): calculate the number of distinct characters in the substring s[l;r]s[l;r].

Input

The first line of the input contains one string ss consisting of no more than 105105 lowercase Latin letters.

The second line of the input contains one integer qq (1q1051≤q≤105) — the number of queries.

The next qq lines contain queries, one per line. Each query is given in the format described in the problem statement. It is guaranteed that there is at least one query of the second type.

output

For each query of the second type print the answer for it — the number of distinct characters in the required substring in this query.

Examples

Input

abacaba
5
2 1 4
1 4 b
1 5 b
2 4 6
2 1 7

Output

3
1
2

正确解法:

原本想着可修改的主席树来着,树状数组加上主席树。

改模板改了好久没过。

操作一:改变某个字符

操作二:统计区间【l,r】不同字符的个数。

有三种方法:

 

26个字母的树状数组:

每次需要for26次,统计这个字母是否在区间内。

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <set>
 6 #include <queue>
 7 #include <stack>
 8 #include <string>
 9 #include <cstring>
10 #include <vector>
11 #include <map>
12 //#include <unordered_map>
13 #define mem( a ,x ) memset( a , x ,sizeof(a) )
14 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
15 #define lson  l ,mid ,pos<<1
16 #define rson mid+1 ,r ,pos<<1|1
17 using namespace std;
18 typedef long long ll ;
19 typedef pair<int ,int> pii;
20 typedef pair<ll ,int> pli;
21 const int inf = 0x3f3f3f3f;
22 const int N = 1e5+100;
23 const ll mod =1e9+7 ;
24 char s[N],kkk;
25 int n,m;
26 int aa,bb,cc;
27 int bit[30][N];
28 int bitsize(int x)
29 {
30     return x&(-x);
31 }
32 void update(int k,int id,int x)
33 {
34     while(id<=n)
35     {
36         bit[k][id]+=x;
37         id+=bitsize(id);
38     }
39 }
40 int query(int k,int id)
41 {
42     int ans=0;
43     while(id>0)
44     {
45         ans+=bit[k][id];
46         id-=bitsize(id);
47     }
48     return ans;
49 }
50 int main()
51 {
52     scanf("%s",s+1);
53     n=strlen(s+1);
54     for(int i=1;i<=n;i++)
55     {
56         update(s[i]-a+1,i,1);
57     }
58     scanf("%d",&m);
59     while(m--)
60     {
61         scanf("%d",&aa);
62         if(aa==1)
63         {
64             scanf("%d %c",&bb,&kkk);
65             update(s[bb]-a+1,bb,-1);
66             s[bb]=kkk;
67             update(s[bb]-a+1,bb,1);
68         }
69         else
70         {
71             scanf("%d%d",&bb,&cc);
72             int ans=0,res;
73             for(int i=1;i<=26;i++)
74             {
75                 res=query(i,cc)-query(i,bb-1);
76                 if(res>0)   ans++;
77             }
78             printf("%d\n",ans);
79         }
80     }
81 
82     return 0;
83 }
View Code

 

26个字母的线段树:

技术图片
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <algorithm>
  5 #include <set>
  6 #include <queue>
  7 #include <stack>
  8 #include <string>
  9 #include <cstring>
 10 #include <vector>
 11 #include <map>
 12 //#include <unordered_map>
 13 #define mem( a ,x ) memset( a , x ,sizeof(a) )
 14 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
 15 #define lson  l ,mid ,pos<<1
 16 #define rson mid+1 ,r ,pos<<1|1
 17 using namespace std;
 18 typedef long long ll ;
 19 typedef pair<int ,int> pii;
 20 typedef pair<ll ,int> pli;
 21 const int inf = 0x3f3f3f3f;
 22 const int N = 1e5+100;
 23 const ll mod =1e9+7 ;
 24 char s[N],kkk;
 25 int n,m;
 26 int aa,bb,cc;
 27 int tree[30][4*N],ans[30],a[N];
 28 void push_up(int rt)
 29 {
 30     for(int i=1;i<=26;i++)
 31         tree[i][rt]=tree[i][rt<<1]+tree[i][rt<<1|1];
 32 }
 33 void build(int rt,int l,int r)
 34 {
 35     if(l==r)
 36     {
 37         tree[a[l]][rt]++;
 38         return;
 39     }
 40     int mid=l+r >>1;
 41     build(rt<<1,l,mid);
 42     build(rt<<1|1,mid+1,r);
 43     push_up(rt);
 44 }
 45 void update(int rt,int p,int x,int y,int l,int r)
 46 {
 47     if(l==r)
 48     {
 49         tree[x][rt]--;
 50         tree[y][rt]++;
 51         return;
 52     }
 53     int mid=l+r>>1;
 54     if(p<=mid)
 55         update(rt<<1,p,x,y,l,mid);
 56     else
 57         update(rt<<1|1,p,x,y,mid+1,r);
 58     push_up(rt);
 59 }
 60 void query(int l,int r,int rt,int L,int R)
 61 {
 62     if(r<=R&&L<=l)
 63     {
 64         for(int i=1;i<=26;i++)
 65             ans[i]+=tree[i][rt];
 66         return ;
 67     }
 68     int mid=l+r>>1;
 69     if(L<=mid)  query(l,mid,rt<<1,L,R);
 70     if(R>mid)   query(mid+1,r,rt<<1|1,L,R);
 71 }
 72 int main()
 73 {
 74     scanf("%s",s+1);
 75     n=strlen(s+1);
 76     for(int i=1;i<=n;i++)
 77         a[i]=s[i]-a+1;
 78     build(1,1,n);
 79     scanf("%d",&m);
 80     while(m--)
 81     {
 82         scanf("%d",&aa);
 83         if(aa==1)
 84         {
 85             scanf("%d %c",&bb,&kkk);
 86             update(1,bb,s[bb]-a+1,kkk-a+1,1,n);
 87             s[bb]=kkk;
 88         }
 89         else
 90         {
 91             scanf("%d%d",&bb,&cc);
 92             int sum=0;
 93             memset(ans,0,sizeof(ans));
 94             query(1,n,1,bb,cc);
 95             for(int i=1;i<=26;i++)
 96                 if(ans[i])
 97                     sum++;
 98             printf("%d\n",sum);
 99         }
100     }
101 
102     return 0;
103 }
View Code

 

统计每个字母的下标。用set来快速删除加入元素。

技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <set>
 6 #include <queue>
 7 #include <stack>
 8 #include <string>
 9 #include <cstring>
10 #include <vector>
11 #include <map>
12 //#include <unordered_map>
13 #define mem( a ,x ) memset( a , x ,sizeof(a) )
14 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
15 #define lson  l ,mid ,pos<<1
16 #define rson mid+1 ,r ,pos<<1|1
17 using namespace std;
18 typedef long long ll ;
19 typedef pair<int ,int> pii;
20 typedef pair<ll ,int> pli;
21 const int inf = 0x3f3f3f3f;
22 const int N = 1e5+100;
23 const ll mod =1e9+7 ;
24 char s[N],kkk;
25 int n,m;
26 int aa,bb,cc;
27 set<int>st[30];
28 set<int>::iterator it;
29 int main()
30 {
31     scanf("%s",s+1);
32     n=strlen(s+1);
33     for(int i=1;i<=n;i++)
34         st[s[i]-a+1].insert(i);
35     scanf("%d",&m);
36     while(m--)
37     {
38         scanf("%d",&aa);
39         if(aa==1)
40         {
41             scanf("%d %c",&bb,&kkk);
42             st[s[bb]-a+1].erase(bb);
43             s[bb]=kkk;
44             st[s[bb]-a+1].insert(bb);
45         }
46         else
47         {
48             scanf("%d%d",&bb,&cc);
49             int ans=0;
50             for(int i=1;i<=26;i++)
51             {
52                 it=st[i].lower_bound(bb);
53                 if(it==st[i].end()) continue;
54                 if((*it)<=cc)
55                     ans++;
56             }
57             printf("%d\n",ans);
58         }
59     }
60 
61     return 0;
62 }
View Code

 

Codeforces Round #590 (Div. 3)

标签:lines   ber   air   cto   letter   ram   namespace   lse   mda   

原文地址:https://www.cnblogs.com/Kaike/p/11617314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!