Ninja 钩爪 (ninja) 题解 --- 2019.10.19

You can to this test. . Hey hey hey

topic:

[Problem Description] 
small Q is a passion of hooks ninja, favorite feeling Feiyanzoubi, one day found a little practice using Q hook 
a good place to claw, decided to show their talents here. 
Ceiling scene may be described as an infinite number of axes of long, small initial Q hung at the origin. There are N number of sit-axis 
labeled annular integer achieved for small Q finger movement. Specific operable to: small Q may be linked to the ring finger, and then swing to the 
position with respect to the axis of symmetry of the ring. Q is small, for example, 3 , the ring 7 , it may be moved by a small Q to the ring 11 . 
Now a question stumped a little Q, how to determine if he could reach a whole point of it? 
[Input format 
of the first row two integers N, M, represents the number of rings and the number of groups to ask 
the next row of total N integers each ring described coordinates (repeated) 
Next M lines contains an integer description interrogation 
[] output format 
co M M rows corresponding to a query, if the small Q can be moved to the target point, output Yes, No or output 
[input] sample 
2  2 
. 1  . 3 
. 3 
. 4 
[sample] output 
No 
Yes 
[data range and Explanatory Note 
to 30% Of the data, M≤N≤ 10 , the absolute value of the input coordinate is less than 1000 . 
For 60 % of the data, M≤N≤ 5000 . 
For 100 % of the data, M≤N≤ 100000 , the absolute value of the input coordinate is less than 10 ^ 18 .

 

For 30% of the score

You can use violence memory search out the answer. Namely, to maintain whether each coordinate up, and then search.

 

For 60% of the score

Observe that the current provided by the coordinates x, then a circular ring movable into the through 2a-x-coordinate. Two consecutive rings (a, b) may be moved to x + (2b-2a) by at.

First consider the number of steps to move the case of a simplified version of the problem is an even number: Ring coordinates set a [1] ~ a [n], for any two rings, may be changed to the coordinate x x + 2 (a [j] -a [i]), the title number is converted to N 2 for which b [i, j] = 2 (a [j] -a [i]), by a finite subtraction can change ^ x = 0 to a target .

According to Shu Pei generalized and extended Euclidean theorems related principle known, has a solution if and only if the target is a multiple of gcd time. Therefore, a pretreatment of all possible 2 (a [j] -a [i]), which obtains the common denominator gcd whether the target can be determined multiples.

For an odd number, can be transformed by enumerating the first step of the program is an even number, namely, to maintain a set represents 0 or 1 step up to the step point set (under mod gcd sense), then check whether the target point in the mod gcd belong to this collection. Complexity bottleneck N ^ 2 number of requirements gcd.

 

To 100% of the fraction

By nature of the Euclidean algorithm operation and Decreases understood gcd (a, b) = gcd (ab, b). Setting p1 = {2 * (a [i] -a [1]) | i> 1} the greatest common divisor, set p2 = {2 * (a [i] -a [j])} is the greatest common divisor, easy to know p1> = p2 (p2 as p1 stringent than constraint). For any i, j p1 simultaneously since 2 * (a [i] -a [1]), 2 * (a [j] -a [1]) constraint, it must also be arbitrary p1 2 * (a [i] -a [1]) - 2 * (a [j] -a [1]) = 2 * (a [i] -a [j]) of about a few, so p1 <= p2. In summary p1 = p2, so that no number N ^ 2 while seeking the gcd, just p1 can be obtained out.

 

 

 Bonus std:

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
const int N=200010;
int n,m;
long long a[N],GCD=0;
set<long long> Set;
long long gcd(long long a,long long b)
{
    return b?gcd(b,a%b):a;
}
long long qabs(long long x){return x<0?-x:x;}
int main()
{
//     freopen("ninja.in","r",stdin);
//     freopen("ninja.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for(int i=2;i<=n;i++)
        GCD=gcd(2LL*qabs(a[i]-a[1]),GCD);
    if(GCD==0)GCD=1000000000LL*1000000000LL; 
    Set.insert(0LL);
    for(int i=1;i<=n;i++)
        Set.insert(((2*a[i])%GCD+GCD)%GCD);
    while(m--)
    {
        long long q;
        scanf("%lld",&q);
        if(Set.find((q%GCD+GCD)%GCD)!=Set.end())
            puts("Yes");
        else
            puts("No");
    }
//     fclose(stdin);
//     fclose(stdout);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/ydclyq/p/11705083.html