• 第五场周赛(字符串卡常个人Rank赛)——题解


    本次题目因为比较简单,除了个别题目,其余题目我只写一个思路不再贴代码。

    先是Div.2的题解

    A题奇怪的优化,把递归函数改成2*fun(...)即可,其实看懂程序也不难,就是求a*2b

    B题你会string吗,直接String变量比较大小即可

    C题数数,没有卡正常方法,可以直接把数转成二进制找1个数,此时复杂度为O(logN),更快的方法是使用__builtin_popcount函数,复杂度为O(m(m为数二进制中1的个数));

    D,E题,看Div.1中本题解释

    所有代码都可以10行内写出,所以我不再给出代码;

    Div.1题解

    A题简单代码优化,区间求和,直接再弄一个sum数组即可

    B题简单字符串处理,因为只能在字符串尾部加字符,所以我的做法是把每个字符给个序号(既位置)存入容器,再分别做三个操作。

    对于1操作,删除存储那个字符的集合即可。

    对于2操作,对应集合加上序号即可。

    对于3操作,在1操作时候维护一个树状数组即可。

    整体时间复杂度为O(QlogN),N为字符个数。但这种写法常数略大,有更优化的思路可以和我探讨一下。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 set<int> dis[26];
     5 vector<pair<int,int>> vis(26,make_pair(0,0));
     6 int q,x,k,tot = 0;
     7 char ch;
     8 int c[100005] = {0};
     9 
    10 inline int lowbit(int x){
    11     return x&(-x);
    12 }
    13 
    14 int update(int i){
    15     while(i <= 100000){
    16         c[i] += 1;
    17         i += lowbit(i);
    18     }
    19 }
    20 
    21 int sum(int i){
    22     int res = 0;
    23     while(i > 0){
    24         res += c[i];
    25         i -= lowbit(i);
    26     }
    27     return res;
    28 }
    29 
    30 int main(){
    31     ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    32     freopen("test6.in","r",stdin);
    33     freopen("test6.out","w",stdout);
    34     int f1 = 0;
    35     cin>>q;
    36     generate(vis.begin(),vis.end(),[&f1](void)->pair<int,int>{return make_pair(f1++,0);});
    37     while(q--){
    38         cin>>x;
    39         if(x == 1){
    40             cin>>k;
    41             if(k > 26)
    42                 continue;
    43             sort(vis.begin(),vis.end(),
    44                 [](pair<int,int> a,pair<int,int> b)->bool{
    45                     if(a.second == b.second)
    46                         return a.first < b.first;
    47                     return a.second > b.second;
    48                 });
    49             vis[k-1].second = 0;
    50             for(auto it:dis[vis[k-1].first]){
    51                 update(it);
    52             }
    53             dis[vis[k-1].first].clear();
    54         }
    55         else if(x == 2){
    56             cin>>ch;
    57             dis[ch-'a'].insert(++tot);
    58             for(auto& a:vis){
    59                 if(a.first == ch-'a'){
    60                     a.second++;
    61                     break;
    62                 }
    63             }
    64         }
    65         else if(x == 3){
    66             cin>>ch;
    67             if(dis[ch-'a'].empty())
    68                 cout << -1 << endl;
    69             else
    70                 cout << *(dis[ch-'a'].begin())-sum(*(dis[ch-'a'].begin())) << endl;
    71         }
    72     }
    73     cerr << clock() << endl;
    74     return 0;
    75 }
    View Code

    C题简单信息检索,标记初次出现位置即可

    D题高级信息检索,把每个前缀都存入map,此时可以使用unordered_map更快,或者建立Trie树即可。好像还有人写exKMP,也没问题,毕竟100+100数据量。

    E题密码破解,马拉车算法裸题。

  • 相关阅读:
    nproc 查看系统可用处理单元数
    c++内存泄露的坑
    内存泄露脚本
    c++内存问题(转)
    tmp
    kprobe
    内存对齐算法
    正则
    P3261 [JLOI2015]城池攻占有趣的做法
    CF1620C BAString题解
  • 原文地址:https://www.cnblogs.com/xenny/p/10116014.html
Copyright © 2020-2023  润新知