AtCoder Beginner Contest 177(E,F)

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,k1] 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 ai1 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(ai1)+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);
    }
}

猜你喜欢

转载自blog.csdn.net/Huah_2018/article/details/108305312