模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int M = 1500 + 10; int n,x,y; struct node { int xx,yy,id; bool operator < (const node &a) const { if(xx-x>=0 && a.xx-x<=0) return 1; if(xx-x<=0 && a.xx-x>=0) return 0; return (yy-y)*(ll)(a.xx-x)<(a.yy-y)*(ll)(xx-x); } }p[M]; vector<int> g[M]; int sz[M]; int ans[M]; void dfs (int o,int u) { sz[u] = 1; for (int &v : g[u]) if (v!=o) { dfs (u, v); sz[u] += sz[v]; } } void dfs2 (int o,int u,int l,int r) { if (sz[u]==1) { ans[p[l].id] = u; return; } int id=l; for (int i=l+1; i<r; ++i) { if (p[i].xx < p[id].xx) { id = i; } } swap(p[id], p[l]); ans[p[l].id] = u; x=p[l].xx, y=p[l].yy; sort (p+l+1, p+r); int sum = l+1; for (int &v : g[u]) if (v!=o) { dfs2 (u, v, sum, sum+sz[v]); sum += sz[v]; } } int main () { scanf ("%d", &n); for (int i=1,u,v; i<n; ++i) { scanf ("%d%d", &u,&v); g[u].emplace_back(v); g[v].emplace_back(u); } for (int i=0; i<n; ++i) { scanf ("%d%d", &p[i].xx, &p[i].yy); p[i].id = i; } dfs (1, 1); dfs2 (1, 1, 0, n); for (int i=0; i<n; ++i) { printf ("%d%c", ans[i], " \n"[i==n-1]); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int M = 2000+10; typedef vector<int> vec; vec g[M]; vec rg[M]; vec vs; bool used[M]; int cmp[M]; int n; void dfs (int u) { used[u] = true; for (int &v : g[u]) if (!used[v]) { dfs (v); } vs.emplace_back(u); } void rdfs (int u,int k) { used[u] = true; cmp[u] = k; for (int &v : rg[u]) if (!used[v]) { rdfs (v, k); } } int scc() { memset (used, false, sizeof(used)); vs.clear(); for (int v=0; v<n; ++v) { if (!used[v]) dfs (v); } memset (used, 0, sizeof(used)); int k = 0; for (int i=vs.size()-1; i>=0; --i) { if (!used[vs[i]]) rdfs (vs[i], k++); } //printf ("%d\n",k); return k; } int main () { scanf ("%d", &n); for (int i=0; i<n; ++i) { for (int j=0; j<n; ++j) { int x; scanf ("%d", &x); if (x) { g[i].emplace_back(j); rg[j].emplace_back(i); } } } printf ("%s\n", scc()==1?"YES" : "NO"); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 vector<bool> isprime; 2 vector<int> mu; 3 void sieve () { 4 isprime.assign(M, true); 5 isprime[0] = isprime[1] = false; 6 for (int i=2; i<M/i; ++i) if (isprime[i]) { 7 for (int j=i*i; j<M; j+=i) { 8 isprime[j] = false; 9 } 10 } 11 mu.assign(M, 1); 12 for (int i=2; i<M; ++i) if (isprime[i]) { 13 if (i<M/i) { 14 for (int j=i*i; j<M; j+=i*i) mu[j] = 0; 15 } 16 for (int j=i; j<M; j+=i) mu[j] *= -1; 17 } 18 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin=new Scanner(System.in); BigInteger a,b; BigInteger big1=BigInteger.ZERO;//0 声明一个大整数并常数值赋值0 BigInteger big2=BigInteger.ONE;//1 BigInteger big3=BigInteger.TEN;//10 BigInteger big4 =new BigInteger("1000");//赋除了0,1,10之外的常数值的方法一 BigInteger big5= BigInteger.valueOf(1000);//没有new赋除了之外的常数值的方法二 //BigInteger bi1 = new BigInteger(55,new Random()); 生成一个个随机的大整数 BigInteger [] f=new BigInteger [1005];//声明大整数数组,并赋值 f[1]=BigInteger.ZERO; f[2]=BigInteger.ONE; f[3]=f[2]; f[4]= BigInteger.valueOf(3);//a[4]=a[2].add(a[2].add(a[2])); System.out.println(f[4]); while(cin.hasNext()) { a=cin.nextBigInteger(); b=cin.nextBigInteger(); System.out.println(a.add(b));//输出a+b System.out.println(a.subtract(b));//输出a-b System.out.println(a.multiply(b));//输出a*b System.out.println(a.divide(b));//输出a/b System.out.println(a.remainder(b));//输出a%b if(a.compareTo(b)==0)System.out.println("a==b"); if(a.compareTo(b)>0)System.out.println("a>b"); if(a.compareTo(b)<0)System.out.println("a<b"); System.out.println(a.abs());//大数a的绝对值 int exponent=cin.nextInt(); System.out.println(a.pow(exponent)); //大整数a的exponent次幂 //返回大整数十进制的字符串表示 System.out.println(a.toString()); //返回大整数p进制的字符串表示 int p=cin.nextInt(); System.out.println(a.toString(p)); } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.math.*; import java.text.*; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin=new Scanner(System.in); int n; while(cin.hasNext())//等效于输入到文件尾 { n = cin.nextInt(); BigInteger fact = new BigInteger("1"); BigInteger dp = new BigInteger("1"); for (int i=2; i<=n; ++i) { dp = dp.multiply(BigInteger.valueOf(i)).add(fact); fact = fact.multiply(BigInteger.valueOf(i)); } BigDecimal ans = new BigDecimal(dp); //BigInteger -> BigDecimal BigDecimal __fact = new BigDecimal(fact); //方法一 //四舍五入到小数点后4位,格式“#.0000” DecimalFormat df = new DecimalFormat("#.0000"); double zz = ans.divide(__fact,10, BigDecimal.ROUND_HALF_UP).doubleValue(); System.out.println(df.format(zz)); //方法二,全部输出 //stripTrailingZeros() :用于去除末尾多余的0 //toPlainString(): 控制不使用科学计数法输出 System.out.println(ans.stripTrailingZeros().toPlainString()); } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//注意:因为 sam 在头部插入了一个 nill 字符(如果没有nill,right集会少 //所以对于 parent树 的叶子: //如果 l(leaf) == l(fa(leaf)) + 1, 那么说明实际上从 fa(leaf) -> leaf这条边实际上是通过走 nill 字符通过的, //及原串实际上是不会走到这个节点的。 //hdu6194 #include<bits/stdc++.h> using namespace std; const int M = 1e5 + 10; char s[M]; struct SAM { static const int kN = M << 1; static const int chN = 26; int fa[kN]; int go[kN][chN]; int l[kN]; int o; int rt; int lst; inline int newNode(int _l) { for (int i=0; i<chN; ++i) { go[o][i] = -1; } l[o] = _l; return o ++; } void Init() { o = 0; rt = lst = newNode(0); fa[rt] = -1; } inline void InsKey() { int p = lst, np = newNode(l[lst]+1); lst = np; fa[np] = rt; } inline void Ins(int c) { int p = lst, np = newNode(l[lst]+1); lst = np; //printf ("%c:%d\n", c+'a', np); while (~p && go[p][c] == -1) go[p][c] = np, p = fa[p]; if (p==-1) fa[np] = rt; else { int q = go[p][c]; if (l[p]+1 == l[q]) fa[np] = q; else { int nq = newNode(l[p]+1); //printf ("%c:%d\n", c+'a', nq); memcpy(go[nq], go[q], sizeof(go[q])); fa[nq] = fa[q]; fa[q] = fa[np] = nq; while (~p && go[p][c] == q) go[p][c] = nq, p = fa[p]; } } } //topo int ord[kN]; int cnt[kN]; int right[kN]; int in[kN]; void topo() { int maxVal = 0; memset (cnt, 0, sizeof(cnt[0])*o); for (int i=0; i<o; ++i) maxVal = max(maxVal, l[i]), ++ cnt[l[i]]; for (int i=1; i<=maxVal; ++i) cnt[i] += cnt[i-1]; for (int i=0; i<o; ++i) ord[-- cnt[l[i]]] = i; } int solve(int k) { topo(); memset (right, 0, sizeof(right[0])*o); memset (in, 0, sizeof(in[0])*o); for (int i=1; i<o; ++i) ++in[fa[i]]; for (int i=1; i<o; ++i) right[i] = !in[i]; for (int i=o-1; i>0; --i) right[fa[ord[i]]] += right[ord[i]]; int ret = 0; for (int i=1; i<o; ++i) { if (k == right[i]) ret += l[i]-l[fa[i]]-(in[i]==0); } return ret; } } sam; int main () { int CASE; scanf ("%d", &CASE); while (CASE --) { int k; scanf ("%d%s", &k, s); sam.Init(); sam.InsKey(); for (int i=0; s[i]; ++i) { sam.Ins(s[i]-'a'); } printf ("%d\n", sam.solve(k)); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <numeric> #include <time.h> #include <bitset> #include <string.h> #include <stack> #include <algorithm> #include <iostream> #include <set> #include <map> #include <math.h> #include <queue> #include <complex> #include <functional> #include <limits.h> using namespace std ; typedef long long ll ; typedef long double ld ; typedef unsigned long long ull ; #ifdef _WIN32 #define LLD "%I64d" #else #define LLD "%lld" #endif #define pi (acos(-1.0)) #define fi first #define se second #define SZ(x) ((int)x.size()) #define lson (o<<1),l,mid #define rson (o<<1|1),mid+1,r #define MP make_pair #define sqr(x) ((x)*(x)) #define ALL(v) (v).begin(),(v).end() #define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC) const double eps = 1e-9 ; const int MOD=(int)1e9+7,BAS=233; inline int sign(double x){return x<-eps?-1:x>eps;} inline int clz(int x){return __builtin_clz(x);} inline int clz(ll x){return __builtin_clzll(x);} inline int lg2(int x){return !x ? -1 : 31-clz(x);} inline int lg2(ll x){return !x ? -1 : 63-clz(x);} int AP (char *s) { unsigned hash=0; for(int i=0; s[i]; i++){ if (i & 1) hash ^= (~((hash<<11)^s[i]^(hash>>5))); else hash ^= ((hash<<7)^s[i]^(hash>>3)); } return hash & 0x7FFFFFFF; } const int M=2000000+10, nill=0; int ls[M], rs[M], rt; int b[M]; struct Node { int sz; unsigned fix; int v; int mk; void init (int _v) { v = _v; mk = 0; } void mark (int _mk) { mk += _mk; v += _mk; } }T[M]; int MY; struct Treap { inline unsigned ran () { static unsigned fix = 91250681; return fix += fix << 2 | 1; } inline int alloc (int _v) { T[MY].init(_v); T[MY].sz=1; T[MY].fix=ran(); ls[MY]=rs[MY]=nill; return MY++; } inline void down (int o) { if (T[o].mk == 0) return; T[ls[o]].mark (T[o].mk); T[rs[o]].mark (T[o].mk); T[o].mk = 0; } inline void up (int o) { T[o].sz = T[ls[o]].sz + T[rs[o]].sz + 1; } void cut (int o,int &a,int &b,int k) { if (T[o].sz<=k) {a=o,b=nill;return;} if (k<=0) {a=nill,b=o;return;} down (o); if (k>T[ls[o]].sz) cut (rs[o],rs[a=o],b,k-T[ls[o]].sz-1); else cut (ls[o],a,ls[b=o],k); up(o); } void Merge (int &o,int a,int b) { if (a==nill) o=b; else if (b==nill) o=a; else if (T[a].fix>T[b].fix) { down(a); Merge(rs[o=a],rs[a],b); up(o); } else { down(b); Merge(ls[o=b],a,ls[b]); up(o); } } int lower (int o,int v) {//求大于等于v的数的个数 if (o == nill) return 0; down(o); if (T[o].v < v) { return lower (rs[o], v); } else { return 1 + T[rs[o]].sz + lower (ls[o], v); } } void build (int &o,int l,int r) { if (l > r) return; int mid = l + r>>1; o = alloc (b[mid]); build (ls[o], l, mid-1); build (rs[o], mid+1, r); up (o); } void del (int v) {//删除已经存在于集合中的数v int num = T[rt].sz - lower (rt, v); int a, b, c; cut (rt, a, b, num); cut (b, b, c, 1); Merge (rt, a, c); } void ins (int v) { int num = T[rt].sz - lower (rt, v); //printf ("num = %d\n", num); int a, b, c; cut (rt, a, b, num); c = alloc(v); Merge (rt, a, c); Merge (rt, rt, b); //printf ("ls:%d , rs:%d\n", T[ls[c]].v, T[rs[c]].v); } void update () { T[rt].mark(-1); } void Print (int o) { if (o==nill) return; down (o); //printf ("%d: %d, %d\n", T[o].v, T[ls[o]].v, T[rs[o]].v); //printf ("%d\n", T[o].sz); Print (ls[o]); printf ("%d ", T[o].v); Print (rs[o]); } void Clear () { rt = nill; T[rt].sz = 0; ls[rt] = rs[rt] = nill; MY = 1; } } my; int n; int a[M]; int main () { //srand(time(0)); my.Clear(); scanf ("%d", &n); ll now = 0; for (int i=1; i<=n; ++i) { scanf ("%d", a+i); now += abs(a[i] - i); //my.ins(a[i] - i); b[i] = a[i] - i; } sort (b+1, b+1+n); my.build (rt, 1, n); ll minn = now; int k = 0; //printf ("%d: %I64d\n", 0, now); for (int i=n, j=0; i>=1 && j<300000; --i, ++j) { //my.Print(rt); now -= abs(a[i] - n); now += abs(a[i] - 1); my.del(a[i] - n); int f = my.lower (rt, 1); //printf ("f=%d, a[%d]=%d\n", f, i, a[i]); now += (T[rt].sz - f) - f; printf ("%d: %I64d\n", i, now); if (now < minn) { k = n-i+1; minn = now; } my.update(); my.ins(a[i] - 1); } printf ("%I64d %d\n", minn, k); return 0; } /* 10 10 1 9 2 8 3 7 4 6 5 */
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const int N = 1e2 + 5; const double EPS = 1e-10; int sign(double x) { //三态函数,减少精度问题 return abs(x) < EPS ? 0 : x < 0 ? -1 : 1; } struct Point { //点的定义 int x, y, id; Point(int x=0, int y=0) : x(x), y(y) {} Point operator + (const Point &rhs) const { //向量加法 return Point(x + rhs.x, y + rhs.y); } Point operator - (const Point &rhs) const { //向量减法 return Point(x - rhs.x, y - rhs.y); } Point operator * (int p) const { //向量乘以标量 return Point(x * p, y * p); } bool operator < (const Point &rhs) const { //点的坐标排序 return x < rhs.x || (x == rhs.x && y < rhs.y); } bool operator == (const Point &rhs) const { //判断同一个点 return x - rhs.x == 0 && y - rhs.y == 0; } void read() { scanf("%d%d", &x, &y); } void print() { printf("(%d, %d)\n", x, y); } }; typedef Point Vector; //向量的定义 typedef vector<Point> Polygon; //多边形的定义。使用函数的前提:多边形poly排好序 int cross(Vector A, Vector B) { //向量叉积,两向量组成的三角形的有向面积的两倍,可判断两向量的方向 return A.x * B.y - A.y * B.x; } /* *凸包,基于水平序的Andrew算法。输入点的集合,返回凸包点的集合。 *凸包边上无点:<=;凸包边上有点:< *时间复杂度O(NlogN) */ Polygon convex_hull(Polygon P) { sort(P.begin(), P.end()); //排序 P.erase(unique(P.begin(), P.end()), P.end()); //删除重复点 int n = P.size(), k = 0; Polygon Q(n*2); for (int i=0; i<n; ++i) { while (k > 1 && cross(Q[k-1]-Q[k-2], P[i]-Q[k-2]) < 0) k--; Q[k++] = P[i]; } for (int t=k, i=n-2; i>=0; --i) { while (k > t && cross(Q[k-1]-Q[k-2], P[i]-Q[k-2]) < 0) k--; Q[k++] = P[i]; } Q.resize(k-1); return Q; } Point p[N]; Polygon poly; bool A[N]; int n; int dot(Vector A, Vector B) { //向量点积:向量长度的乘积再乘上夹角的余弦值,可判断两向量的角度 return A.x * B.x + A.y * B.y; } double length(Vector A) { //向量长度,点积 return sqrt((double)dot(A, A)); } bool spj() { if (n > 3) return false; Vector a = p[1] - p[0], b = p[2] - p[0]; double x1 = a.x, y1 = a.y, x2 = b.x, y2 = b.y; double la = length(a), lb = length(b); x1 /= la; y1 /= la; x2 /= lb; y2 /= lb; return sign(x1-x2) == 0 && sign(y1-y2) == 0; } bool judge() { Polygon res = convex_hull(poly); int sz = res.size(); if (sz == 3) { if (sz == n) { if (spj()) { // 3 points in a line A[p[0].id] = A[p[2].id] = true; return true; } else return false; } else { A[res[0].id] = A[res[1].id] = A[res[2].id] = true; return true; } } else { A[res[0].id] = A[res[2].id] = true; return true; } } int main() { int T; scanf("%d", &T); while (T--) { scanf("%d", &n); poly.clear(); memset(A, false, sizeof(A[0])*(n+1)); for (int i=0; i<n; ++i) { p[i].read(); p[i].id = i; poly.push_back(p[i]); } sort(p, p+n); if (n < 3 || !judge()) puts("NO"); else { puts("YES"); for (int i=0; i<n; ++i) { if (A[i]) printf("%c", 'A'); else printf("%c", 'B'); } puts(""); } } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 15; const int M = 362880; typedef long long LL; int n; LL src, tim; char str[N]; int s[N], s1[N], s2[N]; LL fac[N]; int vis[M]; queue <LL> que; void cantor(int s[], LL num, int k){//康托展开,把一个数字num展开成一个数组s,k是数组长度 int t; bool h[k];//0到k-1,表示是否出现过 memset(h, 0, sizeof(h)); for(int i = 0; i < k; i ++){ t = num / fac[k-i-1]; num = num % fac[k-i-1]; for(int j = 0, pos = 0; ; j ++, pos ++){ if(h[pos]) j --; if(j == t){ h[pos] = true; s[i] = pos + 1; break; } } } } void inv_cantor(int s[], LL &num, int k){//康托逆展开,把一个数组s换算成一个数字num int cnt; num = 0; for(int i = 0; i < k; i ++){ cnt = 0; for(int j = i + 1; j < k; j ++){ if(s[i] > s[j]) cnt ++;//判断几个数小于它 } num += fac[k-i-1] * cnt; } } int bfs(){ if(src == tim) return 0; memset(vis, 0, sizeof(vis)); while(!que.empty()) que.pop(); que.push(src); que.push(0); vis[src] = 1; LL tmp, tmp2, dis; while(!que.empty()){ tmp = que.front(); que.pop(); dis = que.front(); que.pop(); cantor(s, tmp, n); for(int i = 1; i < n; ++ i){ swap(s[0], s[i]); inv_cantor(s, tmp2, n); swap(s[0], s[i]); if(vis[tmp2]) continue; if(tmp2 == tim) return dis+1; vis[tmp2] = 1; que.push(tmp2); que.push(dis+1); } } } int main(){ fac[0] = 1; for(int i = 1; i < N; ++ i){ fac[i] = fac[i-1] * i; } scanf("%d", &n); for(int cas = 1; cas <= 5; ++ cas){ scanf("%s", str); for(int i = 0; i < n; ++ i){ s[i] = str[i] - '1'; } inv_cantor(s, src, n); scanf("%s", str); for(int i = 0; i < n; ++ i){ s[i] = str[i] - '1'; } inv_cantor(s, tim, n); int ans = bfs(); printf("%d\n", ans); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
ll solve(ll l,ll r) { while(r>l){ ll m1=(2*l+r)/3; ll m2=(2*r+l+2)/3; ll ret1 = cal(m1); ll ret2 = cal(m2); //printf ("(%I64d, %I64d)\n", m1, ret1); //printf ("(%I64d, %I64d)\n", m2, ret2); if(ret1>ret2) r=m2-1; else l=m1+1; } return cal(l); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> typedef long long LL; int n; LL dp[25]; void init(){ dp[1] = 0; dp[2] = 1; for(int i = 3; i <= 20; i ++){ dp[i] = (i-1) * (dp[i-1] + dp[i-2]); } } int main(){ init(); while(~scanf("%d", &n)){ printf("%I64d\n", dp[n]); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const int block = 233; struct Query { int l, r; int id; bool operator < (const Query &rhs) const { if (l/block == rhs.l/block) { return r < rhs.r; } return l < rhs.l; } }qu[M]; void solve() { sort(qu, qu+m); l = r = nowAns = 0; for (int i = 0; i < m; ++i) { const Query &q = qu[i]; while (l > q.l) Move(--l, 1); while (r < q.r) Move(++r, 1); while (l < q.l) Move(l++, -1); while (r > q.r) Move(r--, -1); ans[q.id] = nowAns; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define lson o<<1,l,mid #define rson o<<1|1,mid+1,r using namespace std; const int inf = 0x3f3f3f3f; const int N = ((int)3e5 + 5)<<1; char str[N]; int a[N]; struct Segtree { int T[N<<2]; int up(int ls,int rs) { return min(ls, rs); } void build (int o,int l,int r) { if (l == r) { if (l & 1) T[o] = inf; else T[o] = l - (a[l]-1); //printf ("%d: %d\n", l, T[o]); return; } int mid = l+r>>1; build (lson); build(rson); T[o] = up(T[o<<1], T[o<<1|1]); } int ask (int o,int l,int r,int pl,int pr,int id) { if (pl<=l && r<=pr) { if (T[o] > id) { return -1; } if (l == r) return l; } int mid = l+r>>1; int ret = -1; if (pr>mid) ret = ask(rson,pl,pr,id); if (ret!=-1) return ret; if (pl<=mid) ret = ask(lson,pl,pr,id); return ret; } }sgt; char Ma[N]; int Manacher(char s[], int len, int ret[]){ char sep = '#'; for(int i = 0; i < len; i ++){ Ma[i << 1] = sep; Ma[i << 1 | 1] = s[i]; } Ma[len << 1] = sep; len = len << 1 | 1; int R = 0, id = 0, Max = 0; for(int i = 0; i < len; i ++){ if(R > i) ret[i] = min(ret[2*id-i], R-i); else ret[i] = 1; while(i-ret[i] >= 0 && i+ret[i] < len && Ma[i-ret[i]] == Ma[i+ret[i]]) ret[i]++; if(i+ret[i] > R){ R = i+ret[i]; id = i; } Max = max(Max, ret[i]-1); } return Max; } int main(){ int n, len; scanf("%d", &n); for(int i = 0; i < n; i ++){ scanf("%s", str); len = strlen(str); Manacher(str, len, a); //printf("%d\n", Manacher(str, len, a)); len = len<<1|1; /*for(int i = 0; i<len; i ++){ printf("%d", a[i] - 1); printf(i == len-1 ? "\n" : " "); }*/ sgt.build(1,0,len-1); int ans = 0; for (int i=2; i<len; i+=2) { int d = a[i]-1; int res = sgt.ask(1,0,len-1,i,i+d/2,i); //printf ("i=%d,(%d,%d)=%d\n", i, i, i+d/2, res); res = (res-i)>>1; ans = max(ans, res*4); } printf ("%d\n", ans); } return 0; } /* 5 aaaa aa abaabab abrahellehhelleh rachelhellabracadabra */
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> typedef long long ll; inline int clz(int x){return __builtin_clz(x);} inline int clz(ll x){return __builtin_clzll(x);} inline int lg2(int x){return !x ? -1 : 31-clz(x);} inline int lg2(ll x){return !x ? -1 : 63-clz(x);} using namespace std; const int M = 200000+10, mod = (int)1e9+7; int rk[M], sa[M], h[M], st[20][M]; int n, m; char s[M]; char t[M]; int dp[M][32]; int x; void da (char *s,int n,int m) { static int t1[M], t2[M], c[M]; int *x=t1, *y=t2, i,j,k,p=1; memset (c, 0, sizeof(c[0])*m); for (i=0; i<n; i++) c[x[i]=s[i]] ++; for (i=1; i<m; i++) c[i] += c[i-1]; for (i=n-1; i>=0; i--) sa[--c[x[i]]] = i; for (k=1; p<n; k<<=1, m=p) { for (p=0, i=n-k; i<n; i++) y[p++] = i; for (i=0; i<n; i++) if (sa[i]>=k) y[p++] = sa[i]-k; memset (c, 0, sizeof(c[0])*m); for (i=0; i<n; i++) c[x[i]]++; for (i=1; i<m; i++) c[i] += c[i-1]; for (i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i]; for (swap(x,y), x[sa[0]]=0, p=i=1; i<n; i++) x[sa[i]] = y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k] ? p-1 : p++; } memcpy (rk, x, sizeof(x[0])*n); for (i=0, k=0; i<n-1; h[rk[i++]] = k?k--:k) for (j=sa[rk[i]-1]; s[i+k] == s[j+k]; k++); memcpy (st[0], h, sizeof(h[0])*n); for (k=1; 1<<k<=n; k++) for (i=0; i+(1<<k)-1<n; i++) st[k][i] = min (st[k-1][i], st[k-1][i+(1<<k-1)]); } int getlcp (int i,int j) { i = rk[i], j=rk[j]; if (i>j) swap(i, j); i ++; int f = lg2 (j-i+1); return min (st[f][i], st[f][j-(1<<f)+1]); } int main () { scanf ("%d%s", &n, s); scanf ("%d%s", &m, t); scanf ("%d", &x); s[n] = '#'; s[n+1] = 0; strcat (s, t); da (s, n+m+2, 128); memset (dp, -1, sizeof(dp)); dp[0][0] = 0; for (int i=0; i<=n; ++i) { for (int j=0; j<=x; ++j) if (dp[i][j]!=-1) { dp[i+1][j] = max(dp[i+1][j], dp[i][j]); int lcp = getlcp (i, n+dp[i][j]+1); if (lcp == 0) continue; dp[i+lcp][j+1] = max(dp[i+lcp][j+1], dp[i][j] + lcp); } } for (int j=0; j<=x; ++j) { if (dp[n][j] == m) { puts ("YES"); return 0; } } puts ("NO"); return 0; }