• 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
    ");
     67             continue;
     68         }
     69         if(mp[2][n-1]==2||mp[2][n-1]==6){
     70             printf("YES
    ");
     71         }else{
     72             printf("NO
    ");
     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
    ",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
    ",sum);
    53         }
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    取消svn版本控制
    Sublime Text 2搭建Go开发环境(Windows)
    RESTful API 设计指南
    laravel-v5.1分页并带参数
    laravel使用的模板引擎 blade
    控制器中添加DB类才可以操作数据库表中的数据
    简单hello world
    创建控制器命令
    命令创建模型类
    IntelliJ IDEA类头注释和方法注释
  • 原文地址:https://www.cnblogs.com/pengge666/p/11621377.html
Copyright © 2020-2023  润新知