题意:给你一串长度为n的数,这个数可以将后面的数挪到前面来,如果没有小于最开始的那个数的话就输出YES,否则输出NO
题解:如果后面有数字小于第一个数的话就肯定是NO了,这题的坑点就是如果前面很长一串都相同但是后面有一个比前面相同位置的数小的话也要输出NO,因为n是5e5,我们不可能检查每一个串,其实对于这个字符串,我们可以求出这个数的最小表示法的答案,如果这个字符串的最小表示法的第一个字符不是第一个的话就是NO了】
#include <set> #include <map> #include <deque> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <bitset> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; typedef pair<LL, LL> pLL; typedef pair<LL, int> pLi; typedef pair<int, LL> pil;; typedef pair<int, int> pii; typedef unsigned long long uLL; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define bug printf("********* ") #define FIN freopen("input.txt","r",stdin); #define FON freopen("output.txt","w+",stdout); #define IO ios::sync_with_stdio(false),cin.tie(0) #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"] " #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"] " #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"] " LL read() { int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-')f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } const double eps = 1e-8; const int mod = 1e9 + 7; const int maxn = 1e6 + 5; const int INF = 0x3f3f3f3f; const LL INFLL = 0x3f3f3f3f3f3f3f3f; int n; char s[maxn]; int main() { #ifndef ONLINE_JUDGE FIN #endif scanf("%d", &n); scanf("%s", s + 1); for(int i = 1; i <= n; i++) { s[i + n] = s[i]; } bool flag = 0; for(int i = 1; i <= n; i++) { if(s[i] < s[0]) { flag = 1; break; } } if(flag) { cout << "NO" << endl; } else { int i = 1, j = 2, k; while(i <= n && j <= n) { for(k = 0; k <= n && s[i + k] == s[j + k]; k++); if(k == n) break; if(s[i + k] > s[j + k]) { i = i + k + 1; if(i == j)i++; } else { j = j + k + 1; if(i == j) j++; } } int ans = min(i, j); if(ans != 1) cout << "NO" << endl; else cout << "YES" << endl; } return 0; }
最大最小表示法模板
int getMin() { int i = 0, j = 1; int l; while (i < len && j < len) { for (l = 0; l < len; l++) if (str[(i + l) % len] != str[(j + l) % len]) break; if (l >= len) break; if (str[(i + l) % len] > str[(j + l) % len]) { if (i + l + 1 > j) i = i + l + 1; else i = j + 1; } else if (j + l + 1 > i) j = j + l + 1; else j = i + 1; } return i < j ? i : j; } int getMax() { int i = 0, j = 1, k = 0; while (i < len && j < len && k < len) { int t = str[(i + k) % len] - str[(j + k) % len]; if (!t) k++; else { if (t > 0) { if (j + k + 1 > i) j = j + k + 1; else j = i + 1; } else if (i + k + 1 > j) i = i + k + 1; else i = j + 1; k = 0; } } return i < j ? i : j; }