string String string
First use suffix array to preprocess the height, with F (l,r) to indicate the smallest interval, then the final answer is F (l,r)-max (f (L-1,r), F (l,r+1))
Code:
#include <bits/stdc++.h> using namespace std; #define X First #define Y second #define PB push_back #define MP make_pair #define MEM (b) memset (A,b,sizeof (a)) using NA
Mespace std;
const int MAXN = 5E5+100;
int T1[MAXN], t2[maxn], c[maxn],n; BOOL CMP (int *r, int A, int b, int l) {return r[a] = = R[b] && r[a + l] = = r[b + l];} void da (int str[], int
sa[], int zrank[], int height[], int n, int m) {n++;
int I, J, p, *x = t1, *y = t2;
First round Cardinal Sort, if s maximum value is large, can be changed to quick sort for (i = 0; i < m; i++) c[i] = 0;
for (i = 0; i < n; i++) c[x[i] = str[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 (j = 1; J <= N; J <<= 1) {p = 0; Use the SA array to sort the second keyword for (i = n-j; i < n; i++) y[p++] = i;//After the second key is empty the minimum for (i = 0; i < n; i++) if
(Sa[i] >= j) y[p++] = sa[i]-J; So the array y is saved by the second keyword sorted by the result//radix sort the first keyword for (i = 0; i < m; i++) c[i] = 0;
for (i = 0; i < n; i++) c[x[y[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];
Calculates a new x array swap (x, y) based on the SA and X arrays; p = 1;
X[sa[0]] = 0; for (i = 1; i < n; i++) x[sa[i]] = cmp (y, sa[i-1], Sa[i], j)?
P-1: p++;
if (P >= N) break;
m = p;//The maximum value of the next cardinal order} int k = 0;
n--;
for (i = 0; I <= N; i++) zrank[sa[i]] = i;
for (i = 0; i < n; i++) {if (k) k--;
j = Sa[zrank[i]-1];
while (Str[i + K] = = Str[j + K]) k++;
Height[zrank[i]] = k;
}} int M_RANK[MAXN], HEIGHT[MAXN];
int RMQ[MAXN];
int MM[MAXN];
int BEST[30][MAXN];
void initrmq (int n) {mm[0] =-1; for (int i = 1; I <= n; i++) Mm[i] = ((i& (i-1)) = = 0)?
MM[I-1] + 1:mm[i-1];
for (int i = 1; I <= n; i++) best[0][i] = i; for (int i = 1; I <= mm[n], i++) for (int j = 1; j + (1 << i)-1 <= N;
J + +) {int a = Best[i-1][j];
int B = best[i-1][j + (1 << (i-1))];
if (Rmq[a]<rmq[b]) best[i][j] = A;
else best[i][j] = b;
}} int Askrmq (int a, int b) {int t;
t = mm[b-a + 1];
B-= (1 << t)-1; A = Best[t][a];
b = Best[t][b]; Return rmq[a]<rmq[b]?
A:B;
} Char STR[MAXN];
int R[MAXN];
int SA[MAXN];
int Q[MAXN];
int LCP (int a, int b) {//a = M_rank[a]; b = m_rank[b];
if (a==b) return n-sa[a];
if (a>b) swap (A, b);
Return HEIGHT[ASKRMQ (A + 1, b)];
} int main () {int T, K;
scanf ("%d", &t);
while (t--) {scanf ("%d", &k);
scanf ("%s", str);
n = strlen (str);
for (int i = 0; i < n; i++) r[i] = Str[i];
R[n] = 0;
Da (R, SA, M_rank, height, n, 256);
A long long ans = 0;
for (int i = 1; I <= n; i++) {rmq[i] = Height[i];
} INITRMQ (n); memset (Q, 0, sizeof (Q));
for (int i = 0; i+k<=n; i++) {q[i+1] = LCP (i+k,i);
} int ret;
ans=0;
for (int i = 0; i+k-1 <=n; i++) {RET=LCP (i+k-1,i);
Ans = ans+ (Long Long) max (0,ret-max (Q[i], q[i+1]));
} printf ("%lld\n", ans);
} return 0; }Transaction Transaction Transaction
Tree Division, Nlogn, can be tree DP, is on the
Code:
#include <bits/stdc++.h> using namespace std; #define X First #define Y second #define PB push_back #define MP make_pair #define MEM (b) memset (A,b,sizeof (a)) typedef
Long Long ll;
CONST LL mod = 1e9+7;
const int MAXN =1e6+10;
int n,t;
int Ans,root,max; struct node{int v,next,w;}
EDGE[MAXN*2];
int head[maxn],tot,num1,num2;
int Si[maxn],maxv[maxn],vis[maxn];//vis Mark Center of gravity int dis[maxn],a[maxn],tmpsell,tmpbuy; void Init () {tot=ans=0; MEM (head,-1);
MEM (vis,0);
} void Add_edge (int u,int v,int W) {edge[tot].v=v;edge[tot].w=w;edge[tot].next=head[u];head[u]=tot++;}//processing subtree size (fixed)
void Dfssi (int u,int f) {si[u]=1;
maxv[u]=0;
for (int i=head[u];i!=-1;i=edge[i].next) {int v=edge[i].v; if (v==f| |
VIS[V]) continue;
Dfssi (V,u);
SI[U]+=SI[V];
if (Si[v]>maxv[u]) maxv[u]=si[v]; }}//Find center of gravity (fixed) void dfsroot (int r,int u,int f) {if (Si[r]-si[u]>maxv[u])//si[r]-si[u] is the size of the tree above the upper part of U, with the max child of U, find the minimum difference of the maximum child
Node Maxv[u]=si[r]-si[u]; if (mAxv[u]<max) Max=maxv[u],root=u;
for (int i=head[u];i!=-1;i=edge[i].next) {int v=edge[i].v; if (v==f| |
VIS[V]) continue;
Dfsroot (R,v,u);
}}//ask for each point to u distance (custom) void Dfsdis (int u,int d,int f) {tmpsell=min (tmpsell,d-a[u]);
Tmpbuy=min (Tmpbuy,d+a[u]);
for (int i=head[u];i!=-1;i=edge[i].next) {int v=edge[i].v;
if (V!=f&&!vis[v])//Do not cross the other center of Gravity Dfsdis (v,d+edge[i].w,u);
}}//Split side to solve a center of gravity answer (custom) int calc (int u,int d) {int ret=0;
for (int i=head[u];i!=-1;i=edge[i].next) {int v=edge[i].v,w=edge[i].w;
if (!vis[v]) {tmpsell=tmpbuy=1e9+10000;
Dfsdis (v,w,0);
Ret=max (Ret,-a[u]-tmpsell);
Ret=max (ret,a[u]-tmpbuy);
Ret=max (ret,-tmpsell-tmpbuy);
}} return ret;
} void Dfs (int u) {max=n;
Dfssi (u,0);//center of Gravity pretreatment Dfsroot (u,u,0);//Find center of gravity vis[root]=1; Ans=max (Ans,calc (root,0));//Consolidated contribution (fixed. ) for (int I=HEAD[ROOT];I!=-1;I=EDGE[I].NEXT) {int v=edge[i].v;
if (!vis[v]) Dfs (v);
}} int main () {scanf ("%d", &t);
while (t--) {scanf ("%d", &n);
for (int i=1;i<=n;i++) scanf ("%d", &a[i]);
int u,v,w;
Init ();
for (int i=1;i<n;i++) {scanf ("%d%d%d", &u,&v,&w);
Add_edge (u,v,w); Add_edge (V,U,W);
} dfs (1);
printf ("%d\n", ans);
} return 0; } Card Card
The title means to walk a circle, from where to start, the sum of the process will not be less than 0, then ask for the prefix and, from the smallest start to walk on the line.
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
CONST LL mod = 1e9+7;
const int MAXN =2e6+10;
ll N,t,a[maxn],x;
int main () {while
(scanf ("%lld", &n)!=eof) {for
(int i=1;i<=n;i++) scanf ("%lld", &a[i]);
for (int i=1;i<=n;i++) scanf ("%lld", &x), a[i]-=x;
int ans=0;
ll sum=0;
for (int i=2;i<=n;i++) a[i]+=a[i-1];
for (int i=1;i<=n;i++) if (a[i]<sum) sum=a[i],ans=i;
printf ("%d\n", ans%n);
}
return 0;
}