"The sub-entrance exam," the second week of the second test


I do not know why, our team began last week on full drag racing, drift than a ... a
result today we finally test bombed ...
look at the situation of today's test, we could set another at the end of it ...
Do not say, look at the title bar exam.
___

T1 "XXOI 2019" geometric sequence triangle

topic

click here

Examination room thinking

Exam time thought it was a relatively simple question.
However ... \ (LJ \) Gangster full talked \ (50 \) minutes.
This question does not know the idea, directly on the \ (O (N ^ 2) \) storm search.

#include<cstdio>
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}

int N,tot;

signed main(){
    qread(N);
    if(N==100000)return 0&puts("210356");//特判过一组
    for(int i=1;i<=N;++i)for(int j=i;j<=N;++j){
        double x=j*1.0/i,y=j*1.0*x;
        int k=j*1.0*x;
        if(k*1.0!=y||k<j-i||j+i<k||k>N)continue;
        ++tot;
    }
    printf("%d\n",tot);
    return 0;
}

Correct

Gugu Gu ~ ~ ~
___

T2 "SNOI2017" a simple inquiry

topic

click here

Examination room thinking

\ (50pts \) : before storm search \ (2 \) group, then let \ (3 \) special set of data points.
\ (80pts \) : pure Mo team, no optimization.
\ (code-80pts \)

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define LL long long
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}

const int MAXN=5e4;

int N,M,Q,a[MAXN+5];
struct query{
    int l,r,l2,r2,id;
    query(){}
    query(const int L,const int R,const int L2,const int R2,const int I):l(L),r(R),l2(L2),r2(R2),id(I){}
    bool operator<(const query a){return l/M==a.l/M?r/M<a.r/M:l/M<a.l/M;}
}q[MAXN+5];

int l1,r1,l2,r2;
int t1[MAXN+5],t2[MAXN+5],maxx;
LL res[MAXN+5];

signed main(){
    qread(N);
    M=sqrt(N);
    for(int i=1;i<=N;++i)qread(a[i]),maxx=Max(maxx,a[i]);
    qread(Q);
    for(int i=1,l,r,l2,r2;i<=Q;++i){
        qread(l,r,l2,r2);
        q[i]=query(l,r,l2,r2,i);
    }
    sort(q+1,q+Q+1);
    for(int i=1;i<=Q;++i){
        while(r1<q[i].r)++r1,++t1[a[r1]];
        while(r1>q[i].r)--t1[a[r1]],--r1;
        while(l1<q[i].l)--t1[a[l1]],++l1;
        while(l1>q[i].l)--l1,++t1[a[l1]];

        while(r2<q[i].r2)++r2,++t2[a[r2]];
        while(r2>q[i].r2)--t2[a[r2]],--r2;
        while(l2<q[i].l2)--t2[a[l2]],++l2;
        while(l2>q[i].l2)--l2,++t2[a[l2]];

        LL ans=0;
        for(int j=1;j<=maxx;++j)ans+=1ll*t1[j]*t2[j];
        res[q[i].id]=ans;
    }
    for(int i=1;i<=Q;++i)printf("%lld\n",res[i]);
}

answer

First, we secondary differencing this simple formula (I \ (x \) omitted)
\ [\ the begin {aligned} \ {_ the X-SUM = 0} ^ {\ infty} GET (L_1, R_1) \ GET Times (l_2, r_2) = & \ sum _ {x = 0} ^ {\ infty} (get (1, r_1) -get (1, l_1-1)) \ times (get (1, r_2) -get (1 , l_2-1)) \\ = & \ sum _ {x = 0} ^ {\ infty} get (1, r_1) \ times get (1, r_2) -get (1, r_1) \ times get (1, l_2-1) -get (1, l_1-1)
\ times get (1, r_2) + get (1, l_1-1) \ times get (1, l_2-1) \ end {aligned} \] then, we We found that a query from the original two functions becomes a four.
However, this has the advantage, all functions become (get (1, t) \ ) \ form, and, a sub-problem we are transformed into four parts, namely:
\ [\ the aligned} {the begin = & Q_1 \ sum _ {x = 0} ^ {\ infty} get (1, r_1) \ times get (1, r_2) \\ & Q_2 = \ sum _ {x = 0} ^ {\ infty} get (1, r_1) \ times get (1, l_2-1) \\ & Q_3 = \ sum _ {x = 0} ^ {\ infty} get (1, l_1-1) \ times get (1, r_2) \\ & Q_4 = \ sum _ end {aligned} \] {x
= 0} ^ {\ infty} get (1, l_1-1) \ times get (1, l_2-1) \ final answer to this question is sub\ [ans = Q_1-Q_2-
Q_3 + Q_4 \] then there is a problem, how do we find \ (Q_i \) ?
Know will say: Mo algorithm team
but this team Mo algorithm is just an idea, or ideas borrowed from Mo team.
Consideration of an interval \ ([l, r] \ ) for maintenance, the object of maintenance clear: \ (Q_i \) values.
That this \ (Q_i \) value of how to maintain it? It seems the team and Mo have nothing, right?
Yes, this is the place to deformation.
We look, if this is a team of Mo title, then we add and subtract points that ++(--)cnt[point]can be.
But if we want this question ++(--)cnt[point], then, what impact?
If you say that we maintain \ (r \) , then when ++(--)tr[point]the time, we maintain \ (ret = Q_i \) changes in values, is another parenthesis a whole value , so we \ (ret \) should correspond a +(-)tl[point].
If you do not know how to do, it pays to look at the code ...

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}

const int MAXN=5e4;

int N,a[MAXN+5],M,Q,tl[MAXN+5],tr[MAXN+5],ans[MAXN+5],l,r,ret;

struct query{
    int l,r,type,id;
    query(){}
    query(const int L,const int R,const int T,const int I):l(L),r(R),type(T),id(I){}
    bool operator<(const query a){return l/M==a.l/M?r/M<a.r/M:l/M<a.l/M;}
}q[(MAXN<<2)+5];

signed main(){
    M=sqrt(N=rqread());
    rep(i,1,N)qread(a[i]);
    qread(Q);
    for(int i=1,l1,r1,l2,r2;i<=Q;++i){
        qread(l1,r1,l2,r2);//拆询问
        q[i-1<<2]=query(r1,r2,1,i);
        q[i-1<<2|1]=query(l2-1,r1,-1,i);
        q[i-1<<2|2]=query(l1-1,r2,-1,i);
        q[i-1<<2|3]=query(l1-1,l2-1,1,i);
    }
    sort(q,q+(Q<<2));
    for(int i=0;i<(Q<<2);++i){
        if(q[i].l<1||q[i].r<1)continue;
    /*
        我们把一个问题拆成了四个子问题
        考虑其中一个子问题 get(1,l)*get(1,r)
        设 tl 为 l 维护的桶,tr 同理
        当右边的 get 减去 1 后,
    原式=get(1,l)*(get(1,r)-1)
        =get(1,l)*get(1,r)-get(1,l)
        可以看出,当 tr 减去一个一之后,另一个括号被整体减去一次
        所以我们在维护当前桶 tr 和 ret 时,桶 tr - 1 ,但是 ret 要减去一个 tl 整体
    */
        while(l<q[i].l)ret+=tr[a[++l]],++tl[a[l]];
        while(l>q[i].l)ret-=tr[a[l]],--tl[a[l--]];
        while(r<q[i].r)ret+=tl[a[++r]],++tr[a[r]];
        while(r>q[i].r)ret-=tl[a[r]],--tr[a[r--]];
        ans[q[i].id]+=ret*q[i].type;
    }
    for(int i=1;i<=Q;++i)printf("%d\n",ans[i]);
    return 0;
}

T3 "NOIP2016" angry bird

Memories of childhood into the exam horror film

topic

click here

Examination room thinking

When the examination code did not come out, there is not linked to the code ...
First of all, I have discovered is that \ (N \) is very small, and I like the idea of a direct rejection of the pressure, start code violence ...
but then, I do not know the reasons for not bad math, the second letter of the analytical formula I have always considered right ...
and then, holding this question is the idea of self-deception of a wrong title, did not do too much thinking ...
( still unfinished code stickers forget)

#include<cstdio>
#include<algorithm>
using namespace std;
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}

const int MAXN=18;

struct node{
    double x,y;
    node(){}
    node(const double X,const double Y):x(X),y(Y){}
}p[MAXN+5];

struct line{
    double a,b;int tot;
    line(){tot=0;}
    line(const double A,const double B):a(A),b(B){}
}l[MAXN*MAXN+5];
int ind;

int T,N,M;

inline void line(const double x0,const double y0,const double x1,const double y1){
    printf("x0==%.8lf,y0==%.8lf,x1==%.8lf,y1==%.8lf\n",x0,y0,x1,y1);
    ++ind;
    l[ind].b=y0/((x0*x0*(y0-y1-x0+x1))/(x0*x0-x1*x1)+x0);
    l[ind].a=(y0-y1-(x0-x1)*l[ind].b)/(x0*x0-x1*x1);
    return;
}

inline void totline(){
    l[ind].tot=0;
    for(int i=1;i<=N;++i)if(p[i].x*p[i].x*l[ind].a+p[i].x*l[ind].b==p[i].y){
        printf("point %d is on the line\n",i);
        ++l[ind].tot;
    }
}

signed main(){
    qread(T);
    while(T--){
        ind=0;
        qread(N,M);
        for(int i=1;i<=N;++i)scanf("%lf %lf",&p[i].x,&p[i].y);
        for(int i=1;i<=N;++i)for(int j=i+1;j<=N;++j)if(p[i].x!=p[j].x){
            printf("debug:>when i==%d,j==%d\n",i,j);
            line(p[i].x,p[i].y,p[j].x,p[j].y);
            totline();
            printf("line[%d] : %.8lf %.8lf %d\n",ind,l[ind].a,l[ind].b,l[ind].tot);
        }
    }
    return 0;
}

answer

Both methods are used like pressure, wherein the second method is a method of optimization, in this first state, said pressure about:
a defined state \ (DP [S] \) : pig shot is set \ (S \) at minimum cost (binary).
Also need an auxiliary array: \ (Line [I] [J] \) : In \ (I \) and \ (J \) passes on the determined that two functional point set (binary)
As for the two letter analytic formula how to find, this hanging an advanced matrix solution (excerpt from \ (luogu \) Gangster JustinRochester, original ):
suppose to enumerate two piglets coordinates are \ ((x_1, y_1) \ ) and \ ((x_2 , Y_2) \) , then there will be correspondingly:
\ [\} the begin Cases Y_1 = {A} {x_1 ^ 2 + bx_1 \\ \\ Y_2 = A ^ {2} + x_2 bx_2 \ Cases End {} \ ]
it be written in matrix:
\ [\ left [\} the begin {matrix \ Y_1 \ \\ \\ Y_2 \ matrix End {} \ right] = \ left [\ the begin matrix {} \ {x_1} & x_1 ^ 2 \ \ \ \\ {x_2} ^ 2 & x_2 \ end {matrix} \ right] \ times \ left [\ begin {matrix} \ a \ \\ \\ b \ end {matrix} \ right] \]
Obviously, it is possible to obtain:
\ [\ left [\} the begin {Matrix \ A \ B \\ \\ \ Matrix End {} \ right] = \ left [\ the begin Matrix {} \ {x_1} & x_1 ^ 2 \ \ \ \\ {x_2} ^ 2 &
x_2 \ end {matrix} \ right] ^ {- 1} \ times \ left [\ begin {matrix} \ y_1 \ \\ \\ y_2 \ end {matrix} \ right] \] and because
\ [\ left | \ begin { matrix} \ {x_1} ^ 2 & x_1 \\ \\ {x_2} ^ 2 & x_2 \ end {matrix} \ right | = {x_1} ^ 2x_2-x_1 {x_2} ^ 2 = (x_1x_2) x_1x_2 \]
so
\ [\ left [\ begin { matrix} \ {x_1} ^ 2 & x_1 \ \\ \\ {x_2} ^ 2 & x_2 \ end {matrix} \ right] ^ {- 1 } = \ frac {1} { (x_1x_2) x_1x_2} \ left [\ begin {matrix} \ x_2 & -x_1 \ \\ \\ - {x_2} ^ 2 & {x_1} ^ 2 \ end {matrix} \ right] \]
it back to the original equation, available
\ [\ begin {cases} a = {1 \ over (x_1x_2) x_1x_2} \ times (x_2y_1-x_1y_2) \\ \\ b = {1 \ over (x_1x_2) x_1x_2} \
times ({x_1} ^ 2y_2- {x_2} ^ 2y_1) \ end {cases} \] shining this request \ (a, b \) function can be a break out ...

A method \ (O (N ^ 22 ^ N) \)

Once you know the state, like writing a good turn

  • Initialization, \ (DP [0] = 0 \)
  • When there are two (or more) points on the same two letter, \ (DP [S | Line [I] [J]] DP = [S] + 1'd \)
  • When there is a point \ (I \) when only the single shot, \ (DP [S | (<<. 1. 1-I)] DP = [S] + 1'd \)

Then, just after ...
(Note that in certain \ (OJ \) on may not pass, this method is still in jeopardy)

Method II \ (O (N2 ^ N) \)

Our \ (N ^ 2 \) come from?
Because we enumerate two points, thus resulting \ (N ^ 2 \) complexity.
We enumerate two points is actually not necessary.
We just need to enumerate the state \ (S \) minimum point when you can, because this point will be covered anyway, so we forced to resolve at this location.

#include<cstdio>
#include<cstring>
#define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
#define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
const double eps=1e-6;
template<class T>inline void qread(T& x){
    char c;bool f=false;x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int rqread(){
    char c;bool f=false;int x=0;
    while((c=getchar())<'0'||'9'<c)if(c=='-')f=true;
    for(x=(c^48);'0'<=(c=getchar())&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?-x:x;
}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline void getInv(int inv[],const int r,const int MOD)
{inv[0]=inv[1]=1;for(int i=2;i<=r;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;}

const int MAXN=20;

inline bool equal(const double x,const double y)
{return fab(x-y)<eps;}

inline void formula(double& x,double& y,const double a0,const double b0,const double c0,const double a1,const double b1,const double c1){
    y=(a0*c1-a1*c0)/(a0*b1-a1*b0);
    x=(c0-b0*y)/a0;
    return;
}

int T,N,M,dp[(1<<MAXN)+5],line[MAXN+5][MAXN+5],low[(1<<MAXN)+5];

double x[MAXN+5],y[MAXN+5],a,b;

signed main(){
    for(int i=0;i<(1<<MAXN);++i){
        int j=1;
        for(;j<=MAXN&&(i&(1<<j-1));++j);
        low[i]=j;
    }
    qread(T);
    while(T--){
        memset(line,0,sizeof line);
        qread(N,M);
        for(int i=1;i<=N;++i)scanf("%lf %lf",&x[i],&y[i]);
        for(int i=1;i<=N;++i)for(int j=1;j<=N;++j)if(!equal(x[i],x[j])){
            line[i][j]=0;
            formula(a,b,x[i]*x[i],x[i],y[i],x[j]*x[j],x[j],y[j]);
            if(a>-eps)continue;
            for(int k=1;k<=N;++k)if(equal(x[k]*x[k]*a+x[k]*b,y[k]))
                    line[i][j]|=(1<<k-1);
        }
        memset(dp,0x3f,sizeof dp);
        dp[0]=0;
        for(int i=0;i<(1<<N);++i){
            int j=low[i];
            dp[i|(1<<j-1)]=Min(dp[i|(1<<j-1)],dp[i]+1);
            for(int k=1;k<=N;++k)dp[i|line[j][k]]=Min(dp[i|line[j][k]],dp[i]+1);
        }
        printf("%d\n",dp[(1<<N)-1]);
    }
    return 0;
}

Also send a complaint, this question should \ (M \) what's the use?

Guess you like

Origin www.cnblogs.com/Arextre/p/12210485.html