Because today is not modified, so we can only summarize the
And inexplicably rank1, seemingly because of my third problem of violence written roar?
First question
Looks like the Bzoj, ZCG they've done it.
But I didn't do it, I thought about it, it was a thin two-dollar relationship. Minimum cut
According to the Pty paper in the building method to get a bit, calculate K value after found that the figure must be a two-part map can be
And then think about it, random half an hour of data run discovery is a binary graph (this is the proof method of Oi
(I guess some particular nature of the subject determines that this is a dichotomy, yes, that's it)
So it was reassuring to write a two-figure coloring map Run min cut Qaq a dropped Qaq
As for the mathematical proof of the binary chart, it is this:
1, (a, B) = 1, so a, B is not all even
2, consider A, b are odd, may wish to set a=2*x-1,b=2*y-1
Then (2*x-1) ^2+ (2*y-1) ^2=2* (2*x^2-2*x+2*y^2-2*y+1)
It is not difficult to find that the exponent of the subsequent equation 2 is 1, so it is impossible to be a complete square number
Because no edges are built between the even numbers, there is no edge between the odd numbers, so the original is a two-part diagram
It is possible to directly divide the odd couple without the use of bipartite graph dyeing.
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include < iostream> #include <cmath> #include <queue>using namespace std;typedef long long ll;const int maxn=1010; const int Oo=0x7fffffff;int n,ans,s,t;int A[maxn],b[maxn];int h[maxn],cnt=1;int cur[maxn],col[maxn],vis[maxn];bool Check[maxn][maxn];struct edge{int to,next,w;} G[5000010];queue<int>q;int gcd (int a,int b) {return b==0?a:gcd (b,a%b);} void Add (int x,int y,int z=0) {++cnt; G[cnt].to=y; G[CNT].NEXT=H[X]; g[cnt].w=z;h[x]=cnt;} void read (int &num) {Num=0;char Ch=getchar (); while (ch< '! ') Ch=getchar (); while (ch>= ' 0 ' &&ch<= ' 9 ') num=num*10+ch-' 0 ', Ch=getchar ();} BOOL Judge (int a,int b) {int c=gcd (b); if (c!=1) return false; LL now=1ll*a*a+1ll*b*b;int k= (int) (sqrt (now)); if (1ll*k*k!=now) return False;return true; void Get_check () {for (int. i=1;i<=n;++i) {for (int j=i+1;j<=n;++j) {if (judge (A[i],a[j])) {check[i][j]=true;}}} return;} void Paint (int u) {for (int i=h[u];i;i=g[i].next{int v=g[i].to;if (COL[V]) continue;col[v]=3-col[u];p aint (v);} return;} void Get_paint () {for (int. i=1;i<=n;++i) {for (int j=i+1;j<=n;++j) {if (Check[i][j]) Add (i,j), add (J,i);}} for (int i=1;i<=n;++i) {if (!col[i]) col[i]=1,paint (i);}} void Build_graph () {memset (h,0,sizeof (h)); cnt=1; s=0; t=n+1;for (int i=1;i<=n;++i) {for (int j=i+1;j<=n;++j) {if (check[i][j]) {int u=i,v=j;if (col[u]!=1) swap (U,V); Add ( U,v,oo); add (v,u,0);}}} for (int i=1;i<=n;++i) {if (col[i]==1) Add (S,i,b[i]), add (i,s,0), else Add (I,t,b[i]), add (t,i,0);} return;} BOOL BFS () {Q.push (S); for (int i=s;i<=t;++i) Vis[i]=-1;vis[s]=0;while (! Q.empty ()) {int U=q.front (); Q.pop (); for (int i=h[u];i;i=g[i].next) {int v=g[i].to;if (vis[v]==-1&&g[i].w>0) {vis[v]=vis[u]+1; Q.push (v);}} return vis[t]!=-1;} int DFS (int x,int f) {if (x==t| | f==0) return f;int w,used=0;for (int i=cur[x];i;i=g[i].next) {if (vis[g[i].to]==vis[x]+1) {W=f-used;w=dfs (G[i].to,min ( W,G[I].W)); G[i].w-=w; G[i^1].w+=w;if (g[i].w>0) cur[x]=i;used+=w;if (used==f) return used;} if (!used) vis[x]=-1;return used;} void Dinic () {while (BFS ()) {for (int i=s;i<=t;++i) Cur[i]=h[i];ans-=dfs (S,oo);} return;} int main () {freopen ("number.in", "R", stdin), Freopen ("Number.out", "w", stdout); Read (n); for (int i=1;i<=n;++i) Read ( A[i]); for (int i=1;i<=n;++i) read (B[i]), ans+=b[i]; Get_check (); Get_paint (); Build_graph ();d inic ();p rintf ("%d\n", ans); return 0;}
Second question
The second question gives a bunch of inexplicable sets of orthogonal.
Since the time complexity of this topic is determined by the number of points to be read, it is not difficult to think of something imaginary tree
Consider how to use a tree to describe such a relationship
When the size of a set is 1, it's not hard to see that every given point is his father.
The elements of the collection are the elements that he represents to all the points of the root.
Consider the size of a set >1, it is not difficult to find the father of each point is a set of all points in the tree of LCA (i.e., the intersection of all points)
After we have built the tree we consider how to ask for some collection of the intersection, the examination time to think for a long time or to write a virtual tree
When I started writing, I found that this was a bare model for chaining, and then because one endpoint of each chain was the root, we sorted the points we read directly into the DFS order.
So the answer is the sum of the depth of all points minus the depth of the LCA of all adjacent two points and (in fact, this is almost the process of a virtual tree).
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include < cstdlib>using namespace Std;const int maxn=200010;int n,k,x,n,m;int anc[maxn][20];int dep[maxn];int h[maxn],cnt=0; struct Edge{int to,next;} G[maxn<<1];int st[maxn],ed[maxn],tot=0;int s[maxn];bool cmp (const int &A,CONST int &b) {return st[a]< ST[B];} void Add (int x,int y) {++cnt; G[cnt].to=y; g[cnt].next=h[x];h[x]=cnt;} void read (int &num) {Num=0;char Ch=getchar (); while (ch< '! ') Ch=getchar (); while (ch>= ' 0 ' &&ch<= ' 9 ') num=num*10+ch-' 0 ', Ch=getchar ();} int LCA (int p,int q) {if (Dep[p]<dep[q]) swap (P,Q); int log;for (log=0; (1<<log) <=dep[p];++log);--log;for ( int i=log;i>=0;--i) {if (dep[p]-(1<<i) >=dep[q]) p=anc[p][i];} if (p==q) return p;for (int i=log;i>=0;--i) {if (Anc[p][i]!=-1&&anc[q][i]!=anc[p][i]) {P=anc[p][i];q=anc[q] [i];}} return anc[p][0];} void merge (int u,int f) {anc[u][0]=f;dep[u]=dep[f]+1;add (f,u); for (int i=1; (1<<i) <=n;++i) anc[u][i]=-1;for (int i=1; (1<<i) <=n;++i) {if (anc[u][i-1]!=-1) {int a=anc[u][i-1];anc[u][i]=anc[a][i-1];} else break;} return;} void Get_dfs (int u) {st[u]=++tot;for (int i=h[u];i;i=g[i].next) Get_dfs (g[i].to); ed[u]=tot;} int main () {freopen ("legend.in", "R", stdin), Freopen ("Legend.out", "w", stdout); Read (n); n=n+1;for (int i=0; (1<<i) <=n;++i) anc[0][i]=-1;for (int i=1;i<=n;++i) {read (k); if (!k) {merge (i,0); Continue;} Read (x); int now=x;for (int j=2;j<=k;++j) {read (x); Now=lca (now,x);} Merge (I,now);} Get_dfs (0); Read (m), while (m--) {read (k), for (int i=1;i<=k;++i) read (s[i]); sort (s+1,s+k+1,cmp); int ans=dep[s[1]]; for (int i=2;i<=k;++i) {ans+=dep[s[i]];int Now=lca (s[i],s[i-1]); Ans-=dep[now];} printf ("%d\n", ans);} return 0;}
Third question
The code seems to be 7k+.
I don't feel like writing.
Just give it a little bit of a blow.
First consider only the first limitation of the situation, which is very simple
We build the suffix tree, then do it again DFS, heuristic merge all suffixes
Whether the current node is legal if and only if the maximum value of the difference of the adjacent two suffixes cannot exceed the length of the current node
After we consider the second constraint, we consider where the current node first appears
It's not hard to find out what we're asking for is this first occurrence. is a suffix after stitching a suffix
This is what I want to do is to build a suffix automaton in the opposite way, and to maintain it during the heuristic merger.
The problem turned into a simple, recent public ancestor. Qaq so happy.
Yes, if you're going to build two Sam for a problem, write spaly heuristic merge, and then write a tree-chain split.
I don't think there's any need to write Qaq.
6.13 Exam Summary