2021-10-11 T1 string(P5329)

题目传送门:传送门

思维题,赛时写了 $O(n^2)$的暴力,得了 $10pts$ 跑路,被全机房吊打qaq。赛后发现有很多不同的解法,大部分人使用了 $O(nlogn)$ 的算法(杜佬: $merge sort O(nlogn^2)$ 不能过吗??? )。希望写一个 $O(n)$ 算法的我去问了 fxj 学哥,他提示我前面互不相同的那个特殊结论可能会对正解有一定帮助。今天再做的时候,受这个启发,得到了一个贪心策略。

如果当前字符两两不同,考虑除去第 $i$ 个与第 $i-1$ 个的比较,显然只有大于和小于两种情况。前面部分是一样的,这一位分别是这两个字符互换,显然大的那个排名靠前。如果第 $i$ 个大于第 $i-1$ 个,这时直接把 $i-1$ 放到当前记录的头队列的末尾。反之,如果第 $i$ 个小于第 $i-1$个,把 $i-1$ 放到尾队列的队首。证明的话,显然后面还未比较的字符串的前缀都和第 $i$ 个一样,所以与第 $i-1$ 个的比较结果也和第 $i$ 个一样,所以操作是合理的。时间复杂度 $O(n)$。

再来考虑可以相同的情况,所有相同的与后面带比较的字符串就与最后一个的比较结果相同,而编号小的在前,所以只要把连续的相同的顺序记录,然后当做一个整体做上面特殊情况的操作即可。每个都只会被访问 O(1) 次,所以时间复杂度为 $O(n)$。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int BUF_SIZE = 1 << 20;
 5 char buf[BUF_SIZE] , *curP = buf;
 6 void buf_flush() {
 7     if(curP != buf) {
 8         fwrite(buf , (curP - buf)  , 1 , stdout);
 9         curP = buf;        
10     }
11 }
12 void putChar(char c) {
13     *curP++ = c;
14     if(curP == buf + BUF_SIZE)
15         buf_flush();
16 }
17 void write(int x) {
18     static char stk[13];
19     char* p = stk + 12 , *ed = stk + 12;
20     while(x) {
21         *--p = x % 10 + '0';
22         x /= 10;
23     }
24     while(p != ed) putChar(*p++);
25 }
26 
27 const int N = 1000000 + 10;
28 int n;
29 char s[N];
30 int ans[N];
31 signed int main()
32 {
33     freopen("string.in","r",stdin);
34     freopen("string.out","w",stdout);
35     scanf("%d",&n);
36     scanf("%s",s + 1);
37     int l = 0,r = n + 1,pos = 1;
38     for(int i = 2;i <= n;i++)
39     {
40         if(s[i] == s[i-1]) continue;
41         if(s[i] < s[i-1])
42         {
43             for(int j = pos;j < i;j++)
44                 ans[++l] = j;
45             pos = i;
46         }
47         else
48         {
49             for(int j = i - 1;j >= pos;j--)
50                 ans[--r] = j;
51             pos = i;
52         }
53     }
54     for(int i = pos;i <= n;i++)
55         ans[++l] = i;
56     for(int i = 1;i <= n;i++)
57         write(ans[i]),putChar(' ');
58     putChar('\n');
59     buf_flush();
60     return 0;
61 }
View Code

 

posted @ 2021-11-27 21:07  一程山雪  阅读(58)  评论(2)    收藏  举报