7.22 NOIP simulation 7

It is to blow up an exam

T1 solution. Equation

  The test most likely to cheat points of a question, but because of too much time spent T2, I not even a + b = c no sentence. . Violence dropped 40 points.

  First, a + b = c, only one set of solutions.

  Then a = 1, b = 1, the answer is c-1, do not explain.

  For maximum data, we can use a group of specialized exgcd obtained solution, after general solution x + (b / gcd) * k, y + (a / gcd) * k.

  To obtain the number of positive integer solutions.

  Note that there are a lot of special judge, commissioning slowly enough (to change the title this time than I have time to change T3 long)

#include<bits/stdc++.h>
#define m 65535
#define int long long
using namespace std;
int t,a,b,c,x,y;
long long ans;
int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    int gcd=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return gcd;
}
main()
{
    scanf("%lld",&t);
    while(t--)
    {
        ans=0;
        scanf("%lld%lld%lld",&a,&b,&c);
        if(a+b==c&&a>=1&&b>=1)
        {
            puts("1");
            continue;
        }
        if(a<0&&b<0&&c<0)
            a=-a,b=-b,c=-c;
        if(a==1&&b==1)
        {
            ans=c-1;
            if(ans>0&&ans<=65535)
            {
                printf("%lld\n",ans);
                continue;
            }
            if(ans<=0)
                puts("0");
            if(ans>m)
                puts("ZenMeZheMeDuo");
            continue;
        }
        if(t<=100&&a<=1000&&a>=1&&b<=1000&&b>=1&&c>=1&&c<=1000)
        {
            for(int i=1;i<=1000;i++)
                for(int j=1;j<=1000;j++)
                {
                    if(a*i+b*j>c)break;
                    if(a*i+b*j==c)ans++;
                }
            if(ans>m)puts("ZenMeZheMeDuo");
            else printf("%lld\n",ans);
            continue;
        }
        if(a==0&&b==0)
        {
            if(c==0)puts("ZenMeZheMeDuo");
            else puts("0");
            continue;
        }
        if(a==0)
        {
            if(b>0)
            {
                if(c>0&&(!(c%b)))puts("ZenMeZheMeDuo");
                else puts("0");
            }
            if(b<0)
            {
                if(c<0&&(!(c%b)))puts("ZenMeZheMeDuo");
                else puts("0");
            }
            continue;
        }
        if(b==0)
        {
            if(a>0)
            {
                if(c>0&&(!(c%a)))puts("ZenMeZheMeDuo");
                else puts("0");
            }
            if(a<0)
            {
                if(c<0&&(!(c%a)))puts("ZenMeZheMeDuo");
                else puts("0");
            }
            continue;
        }
        if((a<0&&b<0&&c>=0)||(a>0&&b>0&&c<=0))
        {
            puts("0");
            continue;
        }
        if(a<0&&b<0&&c<0)
            a=-a,b=-b,c=-c;
        int gcd=exgcd(a,b,x,y);
        if(c%gcd)
        {
            puts("0");
            continue;
        }
        if(a*b<0)
        {
            puts("ZenMeZheMeDuo");
            continue;
        }
        int k=c/gcd,xx=b/gcd,yy=a/gcd;
        x*=k,y*=k;
        if(xx<0)
            xx=-xx,yy=-yy;
        if(x<=0)
        {
            int xxx=x/xx+1;
            x+=xxx*xx,y-=yy*xxx;
        }
        if(y<=0)
        {
            int xxx=y/yy+1;
            x-=xx*xxx,y+=yy*xxx;
        }
        while(x<=0)
            x+=xx,y-=yy;
        while(y<=0)
            x-=xx,y+=yy;
        if(!x||!y)
        {
            puts("0");
            continue;
        }
        if(x/y<0||y/x<0)
        {
            puts("0");
            continue;
        }
        int aa=x/xx+1,bb=y/yy+1;
        if(!(x%xx))aa--;
        if(!(y%yy))bb--;
        ans=max(aa,bb);
        if(ans>m)puts("ZenMeZheMeDuo");
        else printf("%lld\n",ans);
    }
    return 0;
}

T2.visit

  This exam is most unfortunate that a question, play a positive solution, but because the answer for the special sentence wa 0's (a character change, 70 minutes -> AC)

  Test when first called n ^ 3dp, then began to find the law

  10,5,5 = C(10,5)*C(10,0);    
  10,4,4 = C(10,5)*C(10,1);    10,4,6=C(10,4)*C(10,0);
  10,3,3 = C(10,5)*C(10,2);    10,3,5=C(10,4)*C(10,1);        10,3,7=C(10,3)*C(10,0);
  10,2,2 = C(10,5)*C(10,3);    10,2,4=C(10,4)*C(10,2);        10,2,6=C(10,3)*C(10,1);        10,2,8=C(10,2)*C(10,0);
  10,1,1 = C(10,5)*C(10,4);
  10,0,0 = C(10,5)*C(10,5);

  The table I did not finish, but I feel very clear that the, ANS = C (t, (TNM) / 2) * C (t, t / 2-ABS (nm) / 2);

   Then I finally understand the scope of the final data, mod into a number of prime number multiplication means. . .

  Well, then I began to push crt, code code code, tune over about an hour, and dp on a few points, I feel nothing issue, did not play to beat reassuring to see the T3.

  After the test found himself called this:

  

if(((t%(n+m))&1))
    {
        puts("0");
        return 0;
    }

  ? ? ? ? ? ? ? ? ? ? ? I did what? The% change -, AC. A special card sentenced to 30 points off me. . . .

  Some codes may be unsightly, Renren like (now pushed on the test CRT, Lucas currently code)

  As for the interpretation of the number of combinations, refer to the solution to a problem of others.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 int t,mod,n,m,kk,pp[50];
 5 long long ans,js[1000005],r[50];
 6 long long qpow(long long x,long long y,long long p)
 7 {
 8     long long ans=1;
 9     while(y)
10     {
11         if(y&1)ans=ans*x%p;
12         x=x*x%p;
13         y>>=1;
14     }
15     return ans;
16 }
17 long long C(long long x,long long y,long long p)
18 {
19     js[0]=1;
20     for(int i=1;i<=x;i++)
21     {
22         js[i]=js[i-1]*i%p;
23     }
24     return js[x]*qpow(js[y],p-2,p)%p*qpow(js[x-y],p-2,p)%p;
25 }
26 long long crt()
27 {
28     long long mm=mod,ans=0;
29     for(int i=1;i<=kk;i++)
30     {
31         long long c=mm/pp[i];
32         long long ni=qpow(c,pp[i]-2,pp[i]);
33         ans=(ans+r[i]*ni%mod*c%mod)%mod;
34     }
35     return ans;
36 }
37 long long lu(long long x,long long y,long long p)
38 {
39     long long ans=1;
40     while(x&&y)
41     {
42         long long a=x%p,b=y%p;
43         x/=p,y/=p;
44         if(a<b)return 0;
45         ans=ans*C(a,b,p)%p;
46     }
47     return ans%p;
48 }
49 bool check(long long x)
50 {
51     if(x==1)return false;
52     long long sq=sqrt(x);
53     for(int i=2;i<=sq;i++)
54         if(!(x%i))
55             return false;
56     return true;
57 }
58 long long L(long long x,long long y)
59 {
60     for(int i=1;i<=kk;i++)
61     {
62         int k=pp[i];
63         r[i]=lu(x,y,k);
64     }
65     return crt();
66 }
67 main()
68 {
69     scanf("%lld%lld%lld%lld",&t,&mod,&n,&m);
70     int sq=sqrt(mod)+1;
71     for(int i=1;i<=sq;i++)
72     {
73         if(!(mod%i))
74         {
75             if(check(i))
76             {
77                 pp[++kk]=i;
78             }
79             if((i!=mod/i)&&check(mod/i))
80             {
81                 pp[++kk]=mod/i;
82             }
83         }
84     }
85     if(n<0)n=-n;
86     if(m<0)m=-m;
87     if(n+m!=0)
88     if(((t-(n+m))&1))
89     {
90         puts("0");
91         return 0;
92     }
93     ans=L(t,t/2-(abs(n-m)/2))*L(t,(t-n-m)/2)%mod;
94     printf("%lld",ans);
95     return 0;
96 }

 

T3. Light

  I did not expect a simulation that stuck out my 50 minutes. . . Violence are wrong, lured 20 points, finished the discovery after adding clock so a lot of special cards can be sentenced to 80 points.

  Positive solution is to simulate, but to optimize a bit. First, based on the original, it can be considered directly to the current state of the endpoint: The answer is clearly monotone, can be half the answer.

  In the same state, the horizontal and vertical coordinates and the sum or difference necessarily constant, so we can save the coordinates stored into black block or the sum of the difference vector, a binary vector sorting after each answer.

  But we seem to ignore a problem: How Statistics answer?

  Not miss a very simple conclusion: If a block is elapsed, the light passes through only one of his bound diagonal.

  Certify as follows:

  We gave each two adjacent squares dyed different colors, the same state light only after the same color squares. In addition to the retroreflective two states, two other inevitable reflection mode into another block from one color, i.e., through the lower right -> upper left diagonal and right -> light through the lower left diagonal will not block off the same color, it is unlikely to be the same block through the two diagonals.

  That being the case, then you have a very obvious conclusion: a box is up to twice, twice through the same and opposite diagonal direction.

  After a box is then condition it twice? If and only if the reverse reflection occurs. Similarly, if the reverse reflection occurs, the reverse of the original light ray will re-take over all the paths, therefore, once the reverse reflection occurs, all the block will be subjected to pass through twice. Otherwise, each square only once through.

  Therefore, we can record whether a reverse reflection occurs, if it occurs, the final statistics of the number of answers / 2. When calculating the contribution of each state, only the start node and the end lateral (vertical) coordinate can be subtracted.

  Note reflected the situation is very complex, can be classified discussions. For convenience, the multi-tone several STL good.

#include<bits/stdc++.h>
#define mk(a,b,c) make_pair(a,make_pair(b,c))
using namespace std;
const int zx[4]={-1,-1,1,1},zy[4]={1,-1,1,-1};
int n,m,k;
long long ans=0;
bool vv;
vector<int>h[200005],g[200005];
map<pair<int,pair<int,int> >,bool>c;
map<pair<int,int>,bool>kk;
int main()
{
    scanf("%d%d%d",&n,&m,&k);int kkk=max(n,m);
    for(int i=1;i<=k;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        kk[make_pair(x,y)]=true;
        h[x+y].push_back(x-y);
        g[x-y+kkk].push_back(x+y);
    }
    for(int i=0,x,y;i<=m+1;i++)
    {
        x=0,y=i;
        kk[make_pair(x,y)]=true;
        h[x+y].push_back(x-y);
        g[x-y+kkk].push_back(x+y);
        x=n+1;
        kk[make_pair(x,y)]=true;
        h[x+y].push_back(x-y);
        g[x-y+kkk].push_back(x+y);
    }
    for(int i=0,x,y;i<=n+1;i++)
    {
        x=i,y=0;
        kk[make_pair(x,y)]=true;
        h[x+y].push_back(x-y);
        g[x-y+kkk].push_back(x+y);
        y=m+1;
        kk[make_pair(x,y)]=true;
        h[x+y].push_back(x-y);
        g[x-y+kkk].push_back(x+y);
    }
    for(int i=0;i<=kkk+kkk+2;i++)
        sort(h[i].begin(),h[i].end()),
        sort(g[i].begin(),g[i].end());
    int x,y,zt;
    string ss;
    cin>>x>>y>>ss;
    if(ss=="NE")
        zt=0;
    if(ss=="NW")
        zt=1;
    if(ss=="SE")
        zt=2;
    if(ss=="SW")
        zt=3;
    if(zt==0)
    {
        int cc=*--upper_bound(h[x+y].begin(),h[x+y].end(),x-y),xx=(x+y+cc)>>1,yy=(x+y-cc)>>1;
        if((kk.count(make_pair(xx+1,yy))&&kk.count(make_pair(xx,yy-1)))||((!kk.count(make_pair(xx+1,yy)))&&(!kk.count(make_pair(xx,yy-1)))))
        {
            zt=3,x=xx+1,y=yy-1;
        }
        else if(kk.count(make_pair(xx+1,yy)))
        {
            zt=1,x=xx,y=yy-1;
        }
        else if(kk.count(make_pair(xx,yy-1)))
        {
            zt=2,x=xx+1,y=yy;
        }
    }
    else if(zt==3)
    {
        int cc=*upper_bound(h[x+y].begin(),h[x+y].end(),x-y),xx=(x+y+cc)>>1,yy=(x+y-cc)>>1;
        if((kk.count(make_pair(xx-1,yy))&&kk.count(make_pair(xx,yy+1)))||((!kk.count(make_pair(xx-1,yy)))&&(!kk.count(make_pair(xx,yy+1)))))
        {
            zt=0,x=xx-1,y=yy+1;
        }
        else if(kk.count(make_pair(xx-1,yy)))
        {
            zt=2,x=xx,y=yy+1;
        }
        else if(kk.count(make_pair(xx,yy+1)))
        {
            zt=1,x=xx-1,y=yy;
        }
    }
    else if(zt==1)
    {
        int cc=*--upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),xx=(x-y+cc)>>1,yy=(cc-x+y)>>1;
        if((kk.count(make_pair(xx+1,yy))&&kk.count(make_pair(xx,yy+1)))||((!kk.count(make_pair(xx+1,yy)))&&(!kk.count(make_pair(xx,yy+1)))))
        {
            zt=2,x=xx+1,y=yy+1;
        }
        else if(kk.count(make_pair(xx+1,yy)))
        {
            zt=0,x=xx,y=yy+1;
        }
        else if(kk.count(make_pair(xx,yy+1)))
        {
            zt=3,x=xx+1,y=yy;
        }
    }
    else if(zt==2)
    {
        int cc=*upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),xx=(x-y+cc)>>1,yy=(cc-x+y)>>1;
        if((kk.count(make_pair(xx-1,yy))&&kk.count(make_pair(xx,yy-1)))||((!kk.count(make_pair(xx-1,yy)))&&(!kk.count(make_pair(xx,yy-1)))))
        {
            zt=1,x=xx-1,y=yy-1;
        }
        else if(kk.count(make_pair(xx+1,yy)))
        {
            zt=3,x=xx,y=yy-1;
        }
        else if(kk.count(make_pair(xx,yy+1)))
        {
            zt=0,x=xx-1,y=yy;
        }
    }
    while(!c.count(mk(x,y,zt)))
    {
        c[mk(x,y,zt)]=true;
        if(zt==0)
        {
            int cc=*--upper_bound(h[x+y].begin(),h[x+y].end(),x-y),xx=(x+y+cc)>>1,yy=(x+y-cc)>>1;
            ans+=abs(x-xx);
            if((kk.count(make_pair(xx+1,yy))&&kk.count(make_pair(xx,yy-1)))||((!kk.count(make_pair(xx+1,yy)))&&(!kk.count(make_pair(xx,yy-1)))))
            {
                zt=3,x=xx+1,y=yy-1,vv=true;
            }
            else if(kk.count(make_pair(xx+1,yy)))
            {
                zt=1,x=xx,y=yy-1;
            }
            else if(kk.count(make_pair(xx,yy-1)))
            {
                zt=2,x=xx+1,y=yy;
            }
        }
        else if(zt==3)
        {
            int cc=*upper_bound(h[x+y].begin(),h[x+y].end(),x-y),xx=(x+y+cc)>>1,yy=(x+y-cc)>>1;
            ans+=abs(x-xx);
            if((kk.count(make_pair(xx-1,yy))&&kk.count(make_pair(xx,yy+1)))||((!kk.count(make_pair(xx-1,yy)))&&(!kk.count(make_pair(xx,yy+1)))))
            {
                zt=0,x=xx-1,y=yy+1,vv=true;
            }
            else if(kk.count(make_pair(xx-1,yy)))
            {
                zt=2,x=xx,y=yy+1;
            }
            else if(kk.count(make_pair(xx,yy+1)))
            {
                zt=1,x=xx-1,y=yy;
            }
        }
        else if(zt==1)
        {
            int cc=*--upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),xx=(x-y+cc)>>1,yy=(cc-x+y)>>1;
            ans+=abs(x-xx);
            if((kk.count(make_pair(xx+1,yy))&&kk.count(make_pair(xx,yy+1)))||((!kk.count(make_pair(xx+1,yy)))&&(!kk.count(make_pair(xx,yy+1)))))
            {
                zt=2,x=xx+1,y=yy+1,vv=true;
            }
            else if(kk.count(make_pair(xx+1,yy)))
            {
                zt=0,x=xx,y=yy+1;
            }
            else if(kk.count(make_pair(xx,yy+1)))
            {
                zt=3,x=xx+1,y=yy;
            }
        }
        else if(zt==2)
        {
            int cc=*upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),xx=(x-y+cc)>>1,yy=(cc-x+y)>>1;
            ans+=abs(x-xx);
            if((kk.count(make_pair(xx-1,yy))&&kk.count(make_pair(xx,yy-1)))||((!kk.count(make_pair(xx-1,yy)))&&(!kk.count(make_pair(xx,yy-1)))))
            {
                zt=1,x=xx-1,y=yy-1,vv=true;
            }
            else if(kk.count(make_pair(xx+1,yy)))
            {
                zt=3,x=xx,y=yy-1;
            }
            else if(kk.count(make_pair(xx,yy+1)))
            {
                zt=0,x=xx-1,y=yy;
            }
        }
    }
    printf("%lld\n"vv years /? 2:years);
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/hzoi-cbx/p/11228437.html