E - Coprime
First,judging the g c d ( a 1 , a 2 , . . . , a n ) gcd(a_1,a_2,...,a_n) gcd(a1,a2,...,an) whether equal to 1 1 1.
Then,if not equal to 1 1 1,output “not coprime”,else we judging whether is multiply number’s factory for every < = 1 e 6 <=1e6 <=1e6’ prime。
The problem can be solved in O ( n l o g n ) O(nlogn) O(nlogn).
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,a[N],tot,head[N],nex[N*10],to[N*10];
void add(int u,int v){to[++tot]=v;nex[tot]=head[u];head[u]=tot;}
bool vis[N];
int main()
{
for(int i=2;i<=1000000;i++)
if(!vis[i])
{
for(int j=i;j<=1000000;j+=i)
vis[j]=true,add(j,i);
}
scanf("%d",&n);
int ans=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),ans=__gcd(a[i],ans);
if(ans!=1) printf("not coprime\n");
else
{
memset(vis,false,sizeof(vis));
bool flag=false;
for(int i=1;i<=n&&!flag;i++)
for(int j=head[a[i]];j&&!flag;j=nex[j])
{
if(vis[to[j]]) flag=true;
vis[to[j]]=true;
}
if(flag) printf("setwise coprime\n");
else printf("pairwise coprime\n");
}
}
F I hate Shortest Path Problem
A bad idea
Depart from evey coordinate ( 1 , i ) (1,i) (1,i),move row by row and column by column for each row。
Eevery time move from coordinate ( i , j ) (i,j) (i,j) to somewhere,if not a i < = j < = b i a_i<=j<=b_i ai<=j<=bi then find the minimize k k k so that k > i k>i k>i and a k < = j < = b k a_k<=j<=b_k ak<=j<=bk(But this just find a way so that once query spend O ( l o g 2 n ) O(log^2n) O(log2n) time),then update the answer in section [ i , k − 1 ] [i,k-1] [i,k−1] maintained by segment tree and in k-th row build a new coordinate ( k , j ) (k,j) (k,j),else move to coordinate ( i , b i + 1 ) (i,b_i+1) (i,bi+1) and record the optimal distance cost。
The method is bad because I find not a way maintain once query in O ( l o g n ) O(logn) O(logn) is step 2,total need O ( n l o g 2 n ) O(nlog^2n) O(nlog2n) times,is get TLE.
A good idea
We don’t need consider the cost in row move because we just can move to down or right,so that for a row the row moves step is fixed.
We just maintain arrived the i-th row,for each column,we arrive the column least need cost how many column moves.
We maintained by segment tree.We regard one row’s pair a i , b i a_i,b_i ai,bi as a operation:query the cost move to the a i − 1 a_i-1 ai−1 needed column moves d d d,update the cost for every column j j j( a i < = j < = b i a_i<=j<=b_i ai<=j<=bi) to j − ( a i − 1 ) + d j-(a_i-1)+d j−(ai−1)+d.
Every time we arrived a row,we just query the minmum value moved to column j needed cost.
So that the problem can solved in O ( n l o g n ) O(nlogn) O(nlogn)。
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,t[N<<2],t1[N<<2],t2[N<<2];
void update(int l,int r,int k)
{
t1[k]=t[k]+r-l;t2[k]=t[k];
if(l!=r)
{
int m=l+r>>1;
t[k<<1]=t[k];t[k<<1|1]=t[k]+m+1-l;
}
t[k]=0;
}
int query(int l,int r,int k,int x)
{
if(t[k]) update(l,r,k);
if(l>x) return m+1;
if(r<=x) return t1[k];
int m=l+r>>1;
int a=query(l,m,k<<1,x),b=query(m+1,r,k<<1|1,x);
if(x<=r) a+=x>=m?x-m:0;
else a+=r-m;
t2[k]=min(t2[k<<1],t2[k<<1|1]);
t1[k]=min(t1[k<<1]+r-m,t1[k<<1|1]);
return min(a,b);
}
void update(int l,int r,int k,int x,int y,int d)
{
if(t[k]) update(l,r,k);
if(r<x||l>y) return;
if(l>=x&&r<=y)
{
t[k]=d+l-x;
update(l,r,k);
return;
}
int m=l+r>>1;
update(l,m,k<<1,x,y,d);update(m+1,r,k<<1|1,x,y,d);
t2[k]=min(t2[k<<1],t2[k<<1|1]);
t1[k]=min(t1[k<<1]+r-m,t1[k<<1|1]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,a,b,d;i<=n;i++)
{
scanf("%d%d",&a,&b);
d=min(m+1,query(1,m,1,a-1)+1);
update(1,m,1,a,b,d);
printf("%d\n",t2[1]>=m?-1:t2[1]+i);
}
}