Codeforces Round #590 (Div. 3)【D题:26棵树状数组维护字符出现次数】

A题

题意:给你 n 个数 , 你需要改变这些数使得这 n 个数的值相等 , 并且要求改变后所有数的和需大于等于原来的所有数字的和 , 然后输出满足题意且改变后最小的数值。

AC代码:

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4 #define int long long
 5 signed main(){
 6     int _;
 7     cin>>_;
 8     while(_--){
 9         int n;
10         cin>>n;
11         int arr[n+10];
12         int s=0;
13         for(int i=1;i<=n;i++){
14             cin>>arr[i];
15             s+=arr[i];
16         }
17         int x=s/n;
18         if(s%n==0){
19             cout<<x;
20         }else{
21             cout<<x+1;
22         }
23         cout<<endl;
24     }
25     return 0;
26 } 

B1,B2题

题意:给你个长度为 n 的数组和一个队列 , 队列最多可以同时存在 k 个数。遍历这个数组 , 如果当前数组对应的数在队列中则不做改动 , 如果不在则将它插入队首 , 并且将队尾弹出。遍历完后按照队列顺序输出。

思路:模拟即可【deque+map】

AC代码:

 1 #include<bits/stdc++.h>
 2  
 3 using namespace std;
 4  
 5 #define int long long
 6 map<int,int> vis;
 7 deque<int> q;
 8 signed main(){
 9     int n,k;
10     cin>>n>>k;
11     int temp;
12     for(int i=1;i<=n;i++){
13         scanf("%lld",&temp);
14         if(vis[temp]){
15             continue;
16         }else{
17             vis[temp]++;
18             q.push_front(temp);
19             
20             if(q.size()>k){
21                 int x=q.back();
22                 q.pop_back();
23                 vis[x]--;    
24             }
25         }
26     }
27     deque<int>::iterator it = q.begin();
28     cout<<q.size()<<endl;
29     for(;it!=q.end();it++){
30         printf("%lld ",*it);
31     }
32     return 0;
33 }

C题:

题意:有六种管子 , 其中1、2可以互相转换 , 3、4、5、6可以互相转换  , 然后给你两行管道 , 每行有 n 列问水能不能从左上角(第1行第1列)流到右下角(第2行第n列)

思路:模拟即可。判断是否从row==2行流出。是,则判断流出的水是不是水平的。否则,直接NO。【注意:后面四种的形状只能上下两个都是才能往前走】

AC代码:

  1 #include<bits/stdc++.h>
  2  
  3 using namespace std;
  4  
  5 int main(){
  6     int _;
  7     cin>>_;
  8     while(_--){
  9         int n;
 10         cin>>n;
 11         string s1,s2;
 12         cin>>s1>>s2;
 13         int mp[5][n+10];
 14         int row=1;
 15         int flag=1;
 16         for(int i=0;i<n;i++){
 17             if(!flag){
 18                 break;
 19             }
 20             if(i==0){
 21                 if(s1[i]=='1'||s1[i]=='2'){
 22                     mp[row][i]=1;
 23                 }else{
 24                     mp[row][i]=4;
 25                     row=2;
 26                     if(s2[i]=='1'||s2[i]=='2'){
 27                         flag=0;
 28                         break;
 29                     }else{
 30                         mp[row][i]=6;
 31                     }
 32                 }
 33                 continue;
 34             }
 35             if(row==1){
 36                 if(s1[i]=='1'||s1[i]=='2'){
 37                     mp[row][i]=2;
 38                     continue;
 39                 }else{
 40                     mp[row][i]=4;
 41                     row=2;
 42                     if(s2[i]=='1'||s2[i]=='2'){
 43                         flag=0;
 44                         break;
 45                     }else{
 46                         mp[row][i]=6;
 47                     }
 48                 }
 49             }else{
 50                 if(s2[i]=='1'||s2[i]=='2'){
 51                     mp[row][i]=2;
 52                     continue;
 53                 }else{
 54                     mp[row][i]=5;
 55                     row=1;
 56                     if(s1[i]=='1'||s1[i]=='2'){
 57                         flag=0;
 58                         break;
 59                     }else{
 60                         mp[row][i]=3;
 61                     }
 62                 }
 63             }
 64         }
 65         if(!flag||row==1){
 66             printf("NO\n");
 67             continue;
 68         }
 69         if(mp[2][n-1]==2||mp[2][n-1]==6){
 70             printf("YES\n");
 71         }else{
 72             printf("NO\n");
 73         }
 74     }
 75     return 0;
 76 } 
 77  
 78  
 79  
 80 /*
 81 6
 82 7
 83 2323216
 84 1615124
 85 1
 86 3
 87 4
 88 2
 89 13
 90 24
 91 2
 92 12
 93 34
 94 3
 95 536
 96 345
 97 2
 98 46
 99 54
100  
101 */

D题

题意:给你一个字符串 , 有q个操作:
①、 将 pos 位置的字符改为 c

②、查询 L~ R 区间不同字符的个数

思路1:set模拟实现。

AC代码:

#include<bits/stdc++.h>
 
using namespace std;
set<int> s[30];
char str[150000];
int main(){
        
    
    scanf("%s",str+1);
    for(int i=1;i<=strlen(str+1);i++){
        s[str[i]-'a'].insert(i);
    }
    int _;
    scanf("%d",&_);
    while(_--){
        int T;
        scanf("%d",&T);
        if(T==1){
            int x;
            char c;
            scanf("%d",&x);
            cin>>c;
            s[str[x]-'a'].erase(x);
            s[c-'a'].insert(x);
            str[x]=c;
        }else{
            
            int l,r;//cin>>l>>r;
            scanf("%d%d",&l,&r);
            int ans=0;
            for(int i=0;i<26;i++){
                set<int>::iterator it;
                it=s[i].lower_bound(l);
                if(it==s[i].end()){
                    continue;
                }
                if(*it>=l&&*it<=r)
                    ans++;
                
                    
            }            
            printf("%d\n",ans);    
        }
    }
 
    return 0;
}

思路2:【了解了大佬们的写法】维护26个树状数组,代表每个字母从1到i出现了多少次,对于查询,遍历这26个树状数组看每个字母是否在区间内出现,对于修改,这个位置原来的字母减去1,新来的字母加上1即可.

AC代码:

 1 #include<bits/stdc++.h>// 维护26棵树状数组QAQ 
 2 
 3 using namespace std;
 4 #define int long long
 5 int n;
 6 struct str{
 7     int c[150000];
 8     int lowbit(int x){
 9         return x&(-x);
10     }
11     void update(int x,int v){
12         for(int i=x;i<=n;i+=lowbit(i))  
13             c[i]+=v;
14     }
15     int getsum(int x){
16         int res=0; 
17         for(int i=x;i;i-=lowbit(i))
18             res+=c[i]; 
19         return res;
20     }
21     int query(int l,int r){
22         return getsum(r)-getsum(l-1);
23     }
24 }st[35];
25 signed main(){
26     string s;
27     cin>>s;
28     n=s.size();
29     for(int i=0;i<s.size();i++){
30         st[s[i]-'a'].update(i+1,1);
31     }
32     int Q;
33     cin>>Q;
34     int temp;
35     while(Q--){
36         cin>>temp;
37         if(temp==1){
38             int x;
39             char y;
40             cin>>x>>y;
41             st[s[x-1]-'a'].update(x,-1);
42             s[x-1]=y;
43             st[y-'a'].update(x,1);
44         }else{
45             int sum=0;
46             int L,R;
47             cin>>L>>R;
48             for(int i=0;i<26;i++){
49                 if(st[i].query(L,R)>0)
50                     sum++;
51             }
52             printf("%lld\n",sum);
53         }
54     }
55     return 0;
56 }

猜你喜欢

转载自www.cnblogs.com/pengge666/p/11621379.html