1 /* 2 咱們能夠很是容易的發現咱們構造出來的字符串t有着鮮明的特徵。即t中有大量重複的子串,能夠證實的是t = S + (K-1)*A, A是S串中刪去一段字符串(這段字符串知足既是S的前綴又是S的後綴)。 3 */ 4 #include<cstdio> 5 #include<iostream> 6 7 using namespace std; 8 9 const int maxn = 50 + 5; 10 11 char a[maxn]; 12 int n, k; 13 14 int main(void) { 15 scanf("%d%d", &n, &k); 16 scanf("%s", a + 1); 17 string s1 = "", s2 = ""; int res = 0; 18 for (int i = 1, j = n; i < n; ++ i, -- j) { 19 s1 = s1 + a[i]; 20 s2 = a[j] + s2; 21 if (s1 == s2) res = max(res, i); 22 } 23 int len = n - res; 24 // cout << len << endl; 25 string ans = ""; 26 for (int i = n; i >= n - len + 1; -- i) ans = a[i] + ans; 27 for (int i = 1; i <= n; ++ i) printf("%c", a[i]); 28 for (int i = 1; i < k; ++ i) cout << ans; puts(""); 29 return 0; 30 }
1 /* 2 一個相似導彈攔截的DP+決策單調性優化(這個優化由單調隊列實現) 3 */ 4 #include<cstdio> 5 #include<algorithm> 6 7 using namespace std; 8 9 const int maxn = 2e5 + 5; 10 11 int n, a[maxn], f[maxn], Stack[maxn], val[maxn]; 12 13 14 int main(void) { 15 scanf("%d", &n); 16 for (int i = 1; i <= n; ++ i) scanf("%d", &a[i]); 17 int L = 1, R = 1; 18 Stack[1] = 1; 19 val[1] = 1; 20 int ans = 1; 21 // a值小f值大 和 a值大f值小 22 for (int i = 2; i <= n; ++ i) { 23 while (L <= R && a[Stack[L]] * 2 < a[i]) ++ L; 24 if (L <= R) { 25 int cur = val[L] + 1; 26 ans = max(ans, cur); 27 while (L <= R && cur >= val[R]) -- R; 28 ++ R; Stack[R] = i; val[R] = cur; 29 } else { 30 int cur = 1; 31 ++ R; Stack[R] = i; val[R] = cur; 32 } 33 } 34 printf("%d\n", ans); 35 return 0; 36 }
1 /* 2 咱們維護兩個東西,一個是區間並的前綴f[i],另外一個是區間並的後綴g[i]。若是咱們去掉i這個區間,答案就是f[i-1]這個區間和g[i+1]這個區間的區間並。 3 4 */ 5 #include<bits/stdc++.h> 6 7 using namespace std; 8 9 const int maxn = 3e5 + 5; 10 11 int n, l[maxn], r[maxn]; 12 13 struct node { 14 int l, r; 15 } f[maxn], g[maxn]; 16 17 pair<int, int> Make(int l0, int r0, int l1, int r1) { 18 if (l0 > l1) { 19 swap(l0, l1); swap(r0, r1); 20 } 21 // [l0, r0] [l1, r1] l0 <= l1 22 if (r0 <= l1) return make_pair(-1, -1); 23 if (r0 >= r1) return make_pair(l1, r1); 24 return make_pair(l1, r0); 25 } // 輸入兩個區間,返回他們的並區間 26 27 int Get_Ans(pair<int, int> tmp) { 28 return tmp.second - tmp.first; 29 } //獲得區間tmp的長度。 30 31 int main(void) { 32 scanf("%d", &n); 33 for (int i = 1; i <= n; ++ i) scanf("%d%d", &l[i], &r[i]); 34 35 int L = l[1], R = r[1]; 36 f[1].l = L; f[1].r = R; 37 for (int i = 2; i <= n; ++ i) { 38 pair<int, int> tmp = Make(L, R, l[i], r[i]); 39 L = f[i].l = tmp.first; R = f[i].r = tmp.second; 40 } 41 42 L = l[n]; R = r[n]; 43 g[n].l = L; g[n].r = R; 44 for (int i = n - 1; i >= 1; -- i) { 45 pair<int, int> tmp = Make(L, R, l[i], r[i]); 46 L = g[i].l = tmp.first; R = g[i].r = tmp.second; 47 } 48 49 int ans = max(Get_Ans(make_pair(g[2].l, g[2].r)), Get_Ans(make_pair(f[n - 1].l, f[n - 1].r))); 50 51 for (int i = 2; i < n; ++ i) { 52 ans = max(ans, Get_Ans(Make(f[i - 1].l, f[i - 1].r, g[i + 1].l, g[i + 1].r))); 53 } 54 printf("%d\n", ans); 55 return 0; 56 }
1 /* 2 這題我。。。唉。(由於某個智障錯誤個人代碼比別人的代碼慢了20%,T了11發才發現。。) 3 思路:咱們考慮鏈接好的大數x,能夠發現x%k==0這個條件等價於把x減去好多好多的k,直到把x減到0爲止。因而乎,咱們就發現了一個算法,就是咱們把a[i]*(10^(a[j]的長度))對K取模,獲得一個小於k的數字x2, 4 而後在把a[j]對k取模,獲得一個小於k的數字y2。那麼(x2+y2)%k等價於原來的大數%k。咱們這麼處理後就能夠用map來維護這個東西。計算答案就簡單啦。 5 智障錯誤是:我計算i的時候爲了防止a[i]和a[i]拼在一塊兒的狀況出現,直接在map裏面消除了a[i]的影響,算完後再加上去,這個操做複雜度是log的還帶上一個巨大的常數,結果就T了幾百ms,別人算法的這個操做都是O(1)的。。。。我好菜啊 6 */ 7 #pragma GCC diagnostic error "-std=c++11" 8 #pragma GCC target("avx") 9 #pragma GCC optimize(3) 10 #pragma GCC optimize("Ofast") 11 #pragma GCC optimize("inline") 12 #pragma GCC optimize("-fgcse") 13 #pragma GCC optimize("-fgcse-lm") 14 #pragma GCC optimize("-fipa-sra") 15 #pragma GCC optimize("-ftree-pre") 16 #pragma GCC optimize("-ftree-vrp") 17 #pragma GCC optimize("-fpeephole2") 18 #pragma GCC optimize("-ffast-math") 19 #pragma GCC optimize("-fsched-spec") 20 #pragma GCC optimize("unroll-loops") 21 #pragma GCC optimize("-falign-jumps") 22 #pragma GCC optimize("-falign-loops") 23 #pragma GCC optimize("-falign-labels") 24 #pragma GCC optimize("-fdevirtualize") 25 #pragma GCC optimize("-fcaller-saves") 26 #pragma GCC optimize("-fcrossjumping") 27 #pragma GCC optimize("-fthread-jumps") 28 #pragma GCC optimize("-funroll-loops") 29 #pragma GCC optimize("-fwhole-program") 30 #pragma GCC optimize("-freorder-blocks") 31 #pragma GCC optimize("-fschedule-insns") 32 #pragma GCC optimize("inline-functions") 33 #pragma GCC optimize("-ftree-tail-merge") 34 #pragma GCC optimize("-fschedule-insns2") 35 #pragma GCC optimize("-fstrict-aliasing") 36 #pragma GCC optimize("-fstrict-overflow") 37 #pragma GCC optimize("-falign-functions") 38 #pragma GCC optimize("-fcse-skip-blocks") 39 #pragma GCC optimize("-fcse-follow-jumps") 40 #pragma GCC optimize("-fsched-interblock") 41 #pragma GCC optimize("-fpartial-inlining") 42 #pragma GCC optimize("no-stack-protector") 43 #pragma GCC optimize("-freorder-functions") 44 #pragma GCC optimize("-findirect-inlining") 45 #pragma GCC optimize("-fhoist-adjacent-loads") 46 #pragma GCC optimize("-frerun-cse-after-loop") 47 #pragma GCC optimize("inline-small-functions") 48 #pragma GCC optimize("-finline-small-functions") 49 #pragma GCC optimize("-ftree-switch-conversion") 50 #pragma GCC optimize("-foptimize-sibling-calls") 51 #pragma GCC optimize("-fexpensive-optimizations") 52 #pragma GCC optimize("-funsafe-loop-optimizations") 53 #pragma GCC optimize("inline-functions-called-once") 54 #pragma GCC optimize("-fdelete-null-pointer-checks") 55 #include<iostream> 56 #include<cstdio> 57 #include<map> 58 #define ll long long 59 #define LG 32 60 #define N 200100 61 using namespace std; 62 63 ll n,m,ten[40],num[N],ans; 64 map<ll,ll>cnt[40]; 65 66 inline ll ws(ll u){ll res=0;for(;u;u/=10) res++;return res;} 67 68 int main() 69 { 70 ll i,j,p,q; 71 cin>>n>>m; 72 ten[0]=1; 73 for(i=1;i<=LG;i++) ten[i]=ten[i-1]*10%m; 74 for(i=1;i<=n;i++) 75 { 76 scanf("%lld",&num[i]); 77 cnt[ws(num[i])][num[i]%m]++; 78 } 79 for(i=1;i<=n;i++) 80 { 81 p=num[i]; 82 for(j=1;j<=LG;j++) 83 { 84 p=p*10%m; 85 if(cnt[j].count((m-p)%m)) 86 ans+=cnt[j][(m-p)%m]; 87 } 88 if((num[i]*ten[ws(num[i])]+num[i])%m==0) ans--; 89 } 90 cout<<ans; 91 }
1 /* 2 這題就是貪心啊,咱們能夠知道若是咱們對這顆樹(固然若干次操做後就不是一顆樹了)上加一條邊,那麼這條邊的一頭必定是1(由於這樣最優啊)。而後若是咱們設Mx爲當前最大的dis值,那麼這條邊鏈接的必定是一個dis值爲Mx - 1的節點(由於這樣最優啊)。因而咱們就獲得了一個貪心。寫得優美點就是下面的程序啦! 3 */ 4 #pragma GCC optimize(3) 5 #include<cstdio> 6 #include<vector> 7 8 using namespace std; 9 10 const int maxn = 2e5 + 5; 11 12 int n, ans = 0; 13 vector<int> G[maxn]; 14 15 int dfs(int x, int fat) { 16 int dis = 2; 17 for (unsigned i = 0; i < G[x].size(); ++ i) { 18 int v = G[x][i]; if (v == fat) continue; 19 dis = min(dis, dfs(v, x)); 20 } 21 if (dis == 0 && x != 1 && fat != 1) ++ ans; 22 return (dis + 1) % 3; 23 } 24 25 int main(void) { 26 scanf("%d", &n); 27 for (int i = 1; i < n; ++ i) { 28 int x, y; scanf("%d%d", &x, &y); 29 G[x].push_back(y); 30 G[y].push_back(x); 31 } 32 dfs(1, 0); 33 printf("%d\n", ans); 34 return 0; 35 }
1 /* 2 枚舉(a+b)大小的矩形的邊長,並暴力判斷(注意暴力判斷的順序)可否成立,更新答案。 3 */ 4 #include <bits/stdc++.h> 5 6 #define forn(i, n) for (int i = 0; i < int(n); i++) 7 8 typedef long long li; 9 10 using namespace std; 11 12 const int N = 1000 * 1000; 13 14 int lens[N]; 15 int k; 16 17 li solve(li a, li b){ 18 k = 0; 19 for (li i = 1; i * i <= b; ++i) 20 if (b % i == 0) 21 lens[k++] = i; 22 23 li ans = 2 * (a + b) + 2; 24 li x = a + b; 25 int l = 0; 26 for (li i = 1; i * i <= x; ++i){ 27 if (x % i == 0){ 28 while (l + 1 < k && lens[l + 1] <= i) 29 ++l; 30 if (b / lens[l] <= x / i) 31 ans = min(ans, (i + x / i) * 2); 32 } 33 } 34 35 return ans; 36 } 37 38 int main() { 39 li a, b; 40 scanf("%lld%lld", &a, &b); 41 printf("%lld\n", min(solve(a, b), solve(b, a))); 42 return 0; 43 }