本次題目因為比較簡單,除了個别題目,其餘題目我隻寫一個思路不再貼代碼。
先是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題密碼破解,馬拉車算法裸題。