2017.10.6 QBXT 模拟赛
T1
Sort 一下与原数组比较 ,若有两个数或者没有数发生位置交换 ,则输出YES ,否则输出NO
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <algorithm> #include <cctype> #include <cstdio> #define N 1005000 int n, cnt1, cnt2, sum; struct node { int num, pos; bool operator < (node a)const { if (num != a.num) return num < a.num; else return pos < a.pos; } }a[N]; int main(int argc, char *argv[]) { freopen("sort.in", "r", stdin); freopen("sort.out", "w", stdout); scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d", &a[i].num), a[i].pos=i; std :: sort(a + 1, a + n + 1); for (int i = 1; i <= n; ++i) { if (a[i].pos > i) cnt1++; if (a[i].pos < i) cnt2++; } if (cnt1 == 1 || cnt2 == 1 || (!cnt2 && !cnt1)) puts("YES"); else puts("NO"); return 0; fclose(stdin); fclose(stdout); }
T2
同余方程组
前60%的数据可以用中国剩余定理
后面的数据 用数学构造
X%a1=b1
X%a2=b2
....
X+k1a1=b1
X+k2a2=b2
相减得到 k1a1-k2a2=b1-b2
解这个方程,用exgcd(a1,-a2,k1,k2)
Ax+by=gcd(a,b)
Ax+by=c;
把k1k2回带到原式中,求出x
X0=b1-k1a1
X%a1a2=x0
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> typedef long long LL; using namespace std; LL n,m[5],a[5]; LL exgcd(LL a,LL b,LL &x,LL &y) { if (b == 0) { x = 1, y = 0; return a; } LL r = exgcd(b, a % b, x, y); LL tmp = x; x = y; y = tmp - a / b * y; return r; } inline LL crt() { LL a1 = a[1], a2, m2, d, c, m1=m[1]; for (LL i = 2; i <= 4; ++i) { a2 = a[i], m2 = m[i]; c = a2 - a1; LL x, y; d = exgcd(m1, m2, x, y); x = x * c / d; int mod = m2 / d; x = (mod + x % mod) % mod; a1 += m1 * x; m1 *= mod; } return a1; } int main(int argc, char *argv[]) { freopen("mod.in", "r", stdin); freopen("mod.out", "w", stdout); for(int i = 1; i <= 4; i++) cin >> m[i] >> a[i]; cout << crt() << endl; return 0; fclose(stdin); fclose(stdout); }
T3
可以发现回文串是可以二分的
比如:bbbabcbaabcba 我们以第1个c为中心,发现回文半径是3,大于3一定不是回文串。当回文串长度为偶数的时候,我们需要特殊处理一下。
现在有一个结论:本质不同的回文串个数只有O(N)个
本质不同:字符串本身是不同的。
每一次处理完回文串,我们要把他的hash值记录下来。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <algorithm> #include <cstring> #include <cstdio> #include <map> using namespace std; typedef unsigned long long ULL; typedef long long LL; char s[10005]; ULL h[10005], rh[10005], pw[10005]; int L; ULL hs(int l, int r) { return h[r] - h[l - 1] * pw[r - l + 1]; } ULL rhs(int l, int r) { return rh[l] - rh[r + 1] * pw[r - l + 1]; } struct N { int a[26]; bool ok() { int b[26]; for (int i = 0; i < 26; i++) b[i] = a[i]; sort(b,b + 26); for (int i = 0; i < 25; i++) { if (b[i] > 0 && b[i] == b[i + 1]) return true; } return false; } void clear() { memset(a, 0, sizeof(a)); } }; LL ans = 0; map<ULL, LL> num; map<ULL, N> A; void solve_odd() { for (int i = 1; i <= L; i++) { int l = 1,r = min(i,L - i + 1) + 1; while (r - l > 1) { int mid = (l + r) >> 1; if (hs(i - mid + 1, i + mid - 1) == rhs(i - mid + 1, i + mid - 1)) l = mid; else r = mid; } int p = l; int tmp = p; while (tmp >= 1 && num.find(hs(i - tmp + 1, i + tmp - 1)) == num.end()) tmp--; LL sum = 0; N st; st.clear(); if (tmp >= 1) { sum = num[hs(i - tmp + 1, i + tmp - 1)]; st = A[hs(i - tmp + 1 ,i + tmp - 1)]; } while (tmp < p) { st.a[s[i + tmp]-'a'] += (tmp == 0 ? 1 : 2); if (st.ok()) sum++; num[hs(i - tmp, i + tmp)] = sum; A[hs(i - tmp, i + tmp)] = st; tmp++; } ans += sum; } } void solve_even() { A.clear(); num.clear(); for(int i = 1; i < L; i++) { int l = 1,r = min(i,L - i) + 1; while (r - l > 1) { int mid = (l + r) >> 1; if (hs(i - mid + 1, i + mid) == rhs(i - mid + 1, i + mid)) l = mid; else r = mid; } int p = l,tmp = p; while (tmp >= 1 && num.find(hs(i - tmp + 1, i + tmp)) == num.end()) tmp--; LL sum = 0; N st; st.clear(); if (tmp >= 1) { sum = num[hs(i - tmp + 1, i + tmp)]; st = A[hs(i - tmp + 1, i + tmp)]; } while (tmp < p) { st.a[s[i + tmp + 1] - 'a'] += 2; if (st.ok()) sum++; num[hs(i - tmp, i + tmp + 1)] = sum; A[hs(i - tmp, i + tmp + 1)] = st; tmp++; } ans += sum; } } int main() { freopen("str.in", "r", stdin); freopen("str.out", "w", stdout); scanf("%s", s + 1); L = strlen(s + 1); s[0] = '#'; pw[0] = 1; for(int i = 1; i <= L; i++) pw[i] = pw[i - 1] * 13131 ; for(int i = 1; i <= L; i++) h[i] = h[i - 1] * 13131 + s[i]; for (int i = L; i >= 1; i--) rh[i] = rh[i + 1] * 13131 + s[i]; solve_odd(); solve_even(); printf("%lld\n", ans); fclose(stdout); return 0; }
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。