2021.11.11 Simulation Competition summary

Posted by 448191 on Thu, 11 Nov 2021 20:31:28 +0100

Ⅰ.   String string

Problem Description:

You have two lengths n,m of 01 strand S,T . 

have Q One inquiry, each inquiry is given l1,r1,l2,r2 ,satisfy r1−l1+1=r2−l2+1 . order a=S[l1...r1] , b=T[l2...r2] ,You need to find out ai≠bi Number of position pairs 2 The result of taking the mold.

Input format:

Two positive integers in the first line n,m ,Respectively represent S,T The length of the.

Enter two in the next two lines 01 String representation S and T . 

The next line is an integer Q ,Indicates the number of queries.

next Q Rows, four integers per row l1,r1,l2,r2, Represents a set of queries.

Output format:

For each group of queries, output a number 0 or 1 Indicates the answer.

Data range:

about 30% Data: n,m,q≤5000 ;
about 70% Data: n,m,q≤5×104 ;
about 80% Data: n,m,q≤105 ;
about 100% Data: 1≤n,m,q≤2×1051≤l1≤r1≤n , 1≤l2≤r2≤m . 

 

 

Note that the answer to this question is modular to 2, that is, just answer parity.

 

There are three situations for strings a and b:

1. '0' and '1': contribution is 1;

    2. '0'   And '0': contribution is 0;

3. '1' and '1': the contribution is 0, but the parity is the same as 2.

 

So: we only need to count the parity of the number of 1 in the interval.

 

Code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
int n,m,q,A[200005],B[200005];
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1,*p2;
inline int read()
{
    char ch;int x(0);while((ch=gc)<48);
    do x=x*10+ch-48;while((ch=gc)>=48);
    return x;
}
inline int Read()
{
    char ch;int x(0);while((ch=gc)<48);
    x=ch-48;return x;
}
int main()
{
    n=read(),m=read();
    for(register int i=1;i<=n;++i) A[i]=A[i-1]+Read();
    for(register int i=1;i<=m;++i) B[i]=B[i-1]+Read();
    q=read();
    for(register int i=1,l,r,ll,rr;i<=q;++i)
    l=read(),r=read(),ll=read(),rr=read(),printf("%d\n",(A[r]-A[l-1]+B[rr]-B[ll-1])&1);
    return 0;
}

 

 

Ⅱ.   Grid count

Problem Description:

In the lower left corner is (0,0) ,In the upper right corner is (W,H) On the grid, there are (W+1)×(H+1) A grid.

Now find it on the grid N Two different points so that they are in a straight line. And on this straight line, the distance between adjacent points is not less than D . 

Solution digital analog 109+7 . 

Input format:

The first line is an integer T ,Indicates the number of data groups.

next T Rows, four integers per row N,W,H,D ,The meaning is as described in the title.

Output format:

T that 's ok, An integer per line represents the answer.

Data range:

about 20% Data: N,W,H,D≤10 . 
about 50% Data: W,H,D≤100 . 
For another 20% Data: N≤5 . 
about 100% Data: 1≤N≤501≤W,H,D≤5001≤T≤20 . 

 

 

Front:

1. In a two-dimensional grid starting with (0,0), the number of integer points in a line segment (0,0) − (x,y) is gcd(x,y) − 1 (excluding the two integer endpoints of the line segment)

2. There are n boxes, m of which are selected, and there are at least k boxes between two adjacent boxes. The combination scheme is as follows:

 

 

First of all, I'd like to enumerate two endpoints. The absolute value of the difference between abscissa and ordinate is x and Y. then the number of integer points contained in this is GCD (x, y) - 1. It is mandatory to select two endpoints, and then select n − 2 for the rest,

Find out that the number difference between two adjacent boxes is at least k, that is, the number of boxes between two boxes is at least k − 1. If two endpoints are selected, the length interval boxes of two K − 1 will not be selected, and the number of remaining boxes is only g − 1 − 2(k − 1)

Apply the combination number formula above. It is not difficult to find that it is only related to the abscissa and ordinate difference, so directly enumerate the abscissa and ordinate difference and multiply it by the case number (w − x+1)(h − y+1).

But this difference is an absolute difference, so if it is not a horizontal or vertical line, there are two cases.

Code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define mod 1000000007
using namespace std;
int _,n,w,h,d,C[505][505],Ans;
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,65536,stdin),p1==p2)?EOF:*p1++)
char buf[65536],*p1,*p2;
inline int read()
{
    char ch;int x(0);while((ch=gc)<48);
    do x=x*10+ch-48;while((ch=gc)>=48);
    return x;
}
inline void Pre()
{
    for(register int i=0;i<=500;++i)
        {
            C[i][0]=C[i][i]=1;
            for(register int j=1;j<i;++j) C[i][j]=(1LL*C[i-1][j]+C[i-1][j-1])%mod;
        }
}
inline int Gcd(int x,int y) {return y?Gcd(y,x%y):x;}
inline double Work(int x,int y) {return sqrt(x*x*1.0+y*y);}
inline int Get(int x,int y)
{
    if(!x&&!y) return 0;int g=Gcd(x,y);
    int k=(int)ceil(d/Work(x/g,y/g));if(k*(n-1)>g) return 0;
    int RET=C[g-1-2*(k-1)-(k-1)*(n-3)][n-2];
    if(x&&y) RET=((1LL*RET)<<1)%mod;
    return 1LL*RET*(w-x+1)%mod*(h-y+1)%mod;
}
signed main()
{
    _=read(),Pre();
    for(register int __=1;__<=_;++__)
    {
        n=read(),w=read(),h=read(),d=read(),Ans=0;
        if(n==1) {printf("%lld\n",(w+1)*(h+1));continue;}
        for(register int i=0;i<=w;++i)
            for(register int j=0;j<=h;++j) Ans=(1LL*Ans+Get(i,j))%mod;
        printf("%lld\n",Ans);
    }
    return 0;
}

 

 

Ⅲ.   Tree number tree

Problem Description:

  Input format:

The first line is a positive integer T ,Indicates the number of data groups.

For each set of data, the first row is a positive integer n . 

next n−1 that 's ok, Two positive integers per line u,v ,Represents an edge on a tree.

Output format:

T that 's ok, An integer per row represents the answer to each set of data.

Data range:

about 100% Data: 1≤T≤52≤n≤10e5 , 1≤u,v≤n , u≠v ,The input guarantee is a tree.

 

Firstly, it is not difficult to find that all nodes can be selected for a chain or a binary tree; The chrysanthemum map can only select 3 points at most;

It is not difficult to deduce that the maximum contribution of x is the sum of the two largest contributions in its subtree plus 1;

  

Consider how to maintain?

It is easy to think of the priority queue (heap) (of course, the segment tree can also be used). Maintain each point. Pay attention to "heuristic merging".

 

Code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define mod 1000000007
using namespace std;
int _,n,w,h,d,C[505][505],Ans;
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,65536,stdin),p1==p2)?EOF:*p1++)
char buf[65536],*p1,*p2;
inline int read()
{
    char ch;int x(0);while((ch=gc)<48);
    do x=x*10+ch-48;while((ch=gc)>=48);
    return x;
}
inline void Pre()
{
    for(register int i=0;i<=500;++i)
        {
            C[i][0]=C[i][i]=1;
            for(register int j=1;j<i;++j) C[i][j]=(1LL*C[i-1][j]+C[i-1][j-1])%mod;
        }
}
inline int Gcd(int x,int y) {return y?Gcd(y,x%y):x;}
inline double Work(int x,int y) {return sqrt(x*x*1.0+y*y);}
inline int Get(int x,int y)
{
    if(!x&&!y) return 0;int g=Gcd(x,y);
    int k=(int)ceil(d/Work(x/g,y/g));if(k*(n-1)>g) return 0;
    int RET=C[g-1-2*(k-1)-(k-1)*(n-3)][n-2];
    if(x&&y) RET=((1LL*RET)<<1)%mod;
    return 1LL*RET*(w-x+1)%mod*(h-y+1)%mod;
}
signed main()
{
    _=read(),Pre();
    for(register int __=1;__<=_;++__)
    {
        n=read(),w=read(),h=read(),d=read(),Ans=0;
        if(n==1) {printf("%lld\n",(w+1)*(h+1));continue;}
        for(register int i=0;i<=w;++i)
            for(register int j=0;j<=h;++j) Ans=(1LL*Ans+Get(i,j))%mod;
        printf("%lld\n",Ans);
    }
    return 0;
}