A:Banks
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL mod = (int)1e9+7; const int N = 1e5 + 100; int v[N]; int ans = 0; int l[N], r[N]; int main() { freopen("A.in", "r", stdin); int n; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &v[i]); for(int i = 1; i < n; ++i) r[i] = i + 1; r[n] = 1; for(int i = 2; i <= n; ++i) l[i] = i - 1; l[1] = n; int tot = 0, now = 1; while(true){ if(tot == n) break; if(v[now] < 0){ v[r[now]] += v[now]; v[l[now]] += v[now]; v[now] = -v[now]; tot = 1, ans++; } else{ tot++; } now = r[now]; } printf("%d ", ans); return 0; }
B:Circle of digits
题意:有一个环形的字符串,现在让你把它切成n段,要求切了之后,所有的串的最大值最小。
题解:我们可以知道 这长度为m的字符串中 最大值的那个字符串长度一定是m = n/k(向上取整), 故答案一定是从环上的每个点出发,然后走m步的串中的一个。 然后我们对这些答案排序, 排完序之后,二分答案。 然后对于每次二分完答案,我们都去check答案, 每次都往从1号位置枚举起点,枚举到m就够了,因为从m+1的位置出发一定是前面的一段的一个过程了,就不需要继续枚举答案了。
然后现在有一个问题就是比较, 对于这个字符串来说, 我们hash之后比较字符串的大小, 先二分hash值,找到第一个能使得这段hash值不相同的地方,然后再比较这个位置的信息就好了。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL mod = (int)1e9+7; const int N = 2e5 + 100; ULL base = 131; char s[N]; ULL Hash[N], Hash_val[N]; int n, m, k; void init(){ Hash[0] = 1; for(int i = 1; i < N; ++i) Hash[i] = Hash[i-1] * base; for(int i = 1; i <= 2*n; ++i) Hash_val[i] = Hash_val[i-1] * base + s[i] - '0'; } ULL Get_Hash(int l, int r){ return Hash_val[r] - Hash_val[l-1] * Hash[r-l+1]; } int A[N]; bool cmp(int L1, int L2){ int l = 1, r = m; while(l <= r){ int mid = l+r >> 1; if(Get_Hash(L1, L1+mid-1) == Get_Hash(L2, L2+mid-1)) l = mid + 1; else r = mid - 1; } if(l > m) return false; return s[L1+l-1] < s[L2+l-1]; } bool cmp2(int i, int j){ return cmp(i, j); } bool check(int x){ for(int i = 1; i <= m; ++i){ int b = i; for(int j = 1; j <= k; ++j){ if(cmp(x,b) == false) b = b + m; else b = b + m - 1; } if(b-i >= n) return true; } return false; } int main(){ freopen("B.in","r",stdin); scanf("%d%d", &n, &k); m = (n+k-1)/k; scanf("%s", s+1); for(int i = n+1; i <= n*2; ++i) s[i] = s[i-n]; s[2*n+1] = '