模拟测试7

0、T1现场推模板,浪费大量时间,导致T2时间不足,公式推错。T2不会Crt。

总体节奏稍慢。gcd推导过程混乱。应减少时间损耗。

1、方程的解:exgcd。背模板。理解模板。

skyh等人:a,b>0时,公式最值做差。a||b<0,一堆特判。

我:先把x抬到>=1,y伴随变换,再把y降到>=1,记录差值。

优点:不用很多特判。

失误:未考虑无限解。应加特判:a,b异号。a,b同号时负相关。异号正相关,同升同降。

考虑多种情况,多手模几个点,覆盖所有情况、范围。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define F(i,a,b) for(register int i=a;i<=b;i++)
 5 #define pf(a) printf("%d ",a)
 6 #define phn printf("
")
 7 #define LL long long
 8 #define il inline
 9 #define cst const
10 #define rg register
11 using namespace std;
12 #define int long long
13 int read();
14 int a,b,c;
15 const int MX=65535;
16 il void prtf(cst int x){if(x<=0){puts("0");return ;} if(x<=MX)printf("%lld
",x);else puts("ZenMeZheMeDuo");}
17 int exgcd(int a,int b,int &x,int &y){
18     if(b==0){
19         x=1;y=0;return a;
20     }
21     int d=exgcd(b,a%b,x,y);
22     int t=x;x=y;
23     y=t-a/b*x;
24     return d;
25 }
26 //不合法
27 main(){
28     int T=read();
29     while(T--){
30         a=read();b=read();c=read();
31         if(a+b==c){
32             puts("1");
33         }
34         else if(a==1&&b==1){
35             if(c>=2)prtf(c-1);
36             else puts("0");
37         }
38         else if(a==0||b==0){
39             if(a==0&&b==0){
40                 if(c==0)prtf(70000);
41                 else puts("0");
42             }
43             else {
44                 LL x=a+b;
45                 if(x*c>0){
46                     if(c%x!=0)puts("0");
47                     else prtf(70000);
48                 }
49                 else puts("0");
50             }
51             continue;
52         }
53         else{
54             int x=0,y=0;
55             int d=exgcd(a,b,x,y);
56             if(c%d!=0){
57                 puts("0");continue;
58             }
59             if(c==0){
60                 if(1ll*a*b>0)puts("0");
61                 else prtf(70000);
62                 continue;
63             }
64             if(1ll*a*b<0){
65                 puts("ZenMeZheMeDuo");continue;
66             }
67             int k1=b/d,k2=a/d,p=0;
68             x*=(c/d);y*=(c/d);
69             p=(1-x)/k1;x+=p*k1;if(x<1)x+=k1,p++;
70             y-=p*k2;
71             if(y<1){
72                 puts("0");continue;
73             }
74             p=(1-y)/k2;y+=p*k2;if(y<1)y+=k2,p++;    
75         //    printf("%d %d %d %d %d
",x,y,p,k1,k2);
76             prtf((-p)+1);
77         }
78     }
79 }
80 il int read(){
81     rg int s=0,f=0;rg char ch=getchar();
82     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
83     while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
84     return f?-s:s;
85 }
86 /*
87 g++ 1.cpp -g
88 ./a.out
89 3
90 1 0 3
91 1 1 65536
92 1 2 65537999
93 */
View Code

2、数论模板题。没学exlux,公式推对时间不够用。实际10分,有时间公式改对30分,加P质数特判 理论最大60分。

特判部分分。分析复杂度。对复杂度估计不足,没想到会T,而且特判可多得分。

inv(i)=inv(i+1)*i%p不能适用所有范围。模数较小时最后一项为0,递推前面所有为零。

解决:1、只求%pi阶乘,逆元qpow求。 2、边界min(n,p[i]-1)。

该看代码看代码,想不出来空耗时间。这些东西都相当于板子,用过就会了。

知识如果别人提前学了自己也要跟上,即使少打点题,即使看题解。

组合数部分:决策分类。四个方向移动。有效决策(步数)是哪些。其余怎么走。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cmath>
  5 #define F(i,a,b) for(register int i=a;i<=b;++i)
  6 #define pf(a) printf("%d ",a)
  7 #define PF(a) printf("%lld ",a)
  8 #define phn printf("
")
  9 #define LL long long
 10 #define il inline
 11 #define cst const
 12 #define rg register
 13 using namespace std;
 14 int read();
 15 int n,m,MOD;
 16 LL jc[100010][30],Inv[100010][30];
 17 il LL exgcd(LL a,LL b,LL &x,LL &y){
 18     if(b==0){
 19         x=1;y=0;return a;
 20     }
 21     LL d=exgcd(b,a%b,x,y);
 22     LL t=x;x=y;
 23     y=t-a/b*y;
 24     return d;
 25 }
 26 il LL inv(LL a,LL mod){
 27     LL x,y;
 28     LL d=exgcd(a,mod,x,y);
 29     if(d!=1)return -1;
 30     return (x%mod+mod)%mod;
 31 }
 32 il LL qpow(rg LL x,int k,cst int mod){
 33     rg LL s=1;
 34     while(k){
 35         if(k&1)s=s*x%mod;
 36         x=x*x%mod;k>>=1;
 37     }
 38     return s;
 39 }
 40 int a[30],res[30],tot;
 41 il LL C(LL x,LL y,cst int j){
 42     if(x<y||x<0||y<0)return 0;
 43     if(x==y||y==0)return 1;
 44     return jc[x][j]*qpow(jc[y][j],a[j]-2,a[j])%a[j]*qpow(jc[x-y][j],a[j]-2,a[j])%a[j];
 45 }
 46 /*
 47 il LL power(LL x,LL k,int mod){
 48     LL s=0;
 49     while(k){
 50         if(k&1)s=(s+x)%mod;
 51         x=(x+x)%mod;k>>=1;
 52     }
 53     return s;
 54 }*/
 55 il LL Crt(){
 56     rg LL M=MOD;
 57     LL sum=0;
 58     F(i,1,tot){
 59         LL D=M/a[i];
 60         LL t,y;
 61         exgcd(D,a[i],t,y);
 62         sum=(sum+res[i]*D%M*t%M+M)%M;
 63     }
 64     return (sum+M)%M;
 65 }
 66 il LL lux(LL x,LL y,int j){
 67     if(y==0)return 1;
 68     return C(x%a[j],y%a[j],j)*lux(x/a[j],y/a[j],j)%a[j];
 69 } 
 70 int main(){
 71     int T=read();const int mod=read();MOD=mod;
 72     n=read();m=read();
 73     if(n<0)n=-n;if(m<0)m=-m;
 74     if((n+m>T)||((T-n-m)%2==1)){
 75         puts("0");return 0;
 76     }
 77     int x=mod;
 78 //    F(j,1,cnt)if((x%prm[j])==0){a[++tot]=prm[j];x/=prm[j];}
 79     const int end=sqrt(x);
 80     F(i,2,end)if(x%i==0){a[++tot]=i;x/=i;}
 81     if(x>1)a[++tot]=x;//pf(tot);pf(a[tot]);phn;
 82     F(j,1,tot)jc[0][j]=1;
 83     F(j,1,tot){
 84         F(i,1,T)jc[i][j]=jc[i-1][j]*i%a[j];
 85     }
 86 //    pf(8848);phn;
 87     LL ans=0,s=1,w=1;
 88     int k=T-n-m;
 89     for(int i=0;i<=k;i+=2){
 90         F(j,1,tot){
 91             res[j]=(res[j]+lux(T,i>>1,j)*lux(T-(i>>1),n+(i>>1),j)%a[j]*lux(T-n-i,(k-i)>>1,j)%a[j])%a[j];
 92         }        
 93     }
 94     printf("%lld",Crt());
 95 }
 96 il int read(){
 97     rg int s=0,f=0;rg char ch=getchar();
 98     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
 99     while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
100     return f?-s:s;
101 }
102 /*
103 g++ 6.cpp -g
104 ./a.out
105 12 1000000007
106 2 2 
107 */
View Code

3、光:

60分开数组小模拟。100分数组只记录障碍大模拟。

60分小细节:1、0,n+1,m+1边界转为障碍,避免特判。

        2、const int a={1,1,-1,-1}......

      3、原路反弹直接跳回起点减少时间。

70分(10分cout n*m):

特判cout可以无形中多拿部分分。

搜索思路:

数组记录障碍、经过状态。

边界设为障碍省得特判。

递归:退出条件,ans统计,

下层转移方向:1、无障碍 2、有障碍:障碍状态。

#include<cstdio>
#include<iostream>
#include<cstring>
#define F(i,a,b) for(register int i=a;i<=b;i++)
#define pf(a) printf("%d ",a)
#define phn printf("
")
#define LL long long
#define il inline
#define cst const
#define rg register
using namespace std;
int read();
int n,m,k,sx,sy;
bool a[1003][1003];
bool  c[1003][1003][4];
bool vis[1003][1003];
int X[6]={1,-1,1,-1},Y[6]={1,1,-1,-1};
int sum,las;
void dfs(const rg int x,const rg int y,const rg int p){
    if(!vis[x][y]){
        vis[x][y]=1;sum++;
    }
    else if(c[x][y][p]){
        return ;
    }
    c[x][y][p]=1;
    if(!a[x+X[p]][y+Y[p]]){
        dfs(x+X[p],y+Y[p],p);
    }
    else {
        const  int tx=x+X[p],ty=y+Y[p];
        if(a[tx][y]==1&&a[x][ty]==0){
            F(i,0,3)if((X[i]==x-tx)&&(Y[i]==Y[p])){dfs(x,ty,i);break;}
        }
        else if(a[tx][y]==0&&a[x][ty]==1){
            F(i,0,3)if((X[i]==X[p])&&(Y[i]==y-ty)){dfs(tx,y,i);break;}
            
        }
        else {
            las=3-las;    
            dfs(sx,sy,las);    
        }
    }
}
void work1(){
    int x,y;
    F(i,1,k){x=read();y=read();a[x][y]=1;}
    sx=read();sy=read();
    char str[3];scanf("%s",str);
    if(str[0]=='N')x=-1;else x=1;
    if(str[1]=='E')y=1;else y=-1;
    F(i,0,m+1)a[0][i]=a[n+1][i]=1;
    F(i,0,n+1)a[i][0]=a[i][m+1]=1;
    int p=0;
    F(i,0,3)if(x==X[i]&&y==Y[i]){p=i;break;}
    las=p;
    dfs(sx,sy,p);
    printf("%d
",sum);
}
int main(){
    n=read();m=read();k=read();
    if(n<=1000&&m<=1000)work1();
    else printf("%lld",1ll*n*m);
}
il int read(){
    int s=0,f=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
    return f?-s:s;
}
/*
g++ 3.cpp -g
./a.out
3 3 0
2 2 SE
*/
View Code

100分:

哪些是必要的,哪些可以忽视,或暂时忽视。

忽视不必要的从而增大整体效益。奥卡母剃刀。

自律。

解析几何性质。二分。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#define F(i,a,b) for(register int i=a;i<=b;i++)
#define pf(a) printf("%d ",a)
#define phn printf("
")
#define LL long long
#define il inline
#define cst const
#define rg register
using namespace std;
int read();
int n,m,k,sx,sy;
LL ans;int cishu,org,secs,fanhui;
#define NX 200300
map<pair<int,int>,bool >ditu;
vector<int>q1[NX<<1],q2[NX<<1];//q1:/差,q2:和.
#define mp(a,b) make_pair(a,b)
int tot;
void dfs(int x,int y,int d){
//    printf("%d %d %d: ",x,y,d);
//    tot++;
//    if(tot==8){
//        while(1);
//    }
    if(secs){
        return ;
    }
    if(d==1){
        int w=x-y+m+1;
        int va=(*upper_bound(q1[w].begin(),q1[w].end(),x))-1,vb;
        vb=va-w+m+1;
    //    printf("%d %d
",va,vb);
        //if(va==4&&vb==2){
        //    printf("%d %d
",x,y);while(1);
        //}
        if(org==d&&sx-sy+m+1==w&&sx>=x&&sx<=va){
            cishu++;
        //    pf(8848);phn;
            if(cishu!=1){
                ans+=abs(sx-x);secs=1;return ;
            }
        }
        ans+=abs(va-x)+1;
        int na=0,nb=0;
        if(ditu[mp(va+1,vb)])na=1;
        if(ditu[mp(va,vb+1)])nb=1;
        if(na&&!nb)dfs(va,vb+1,4);
        else if(nb&&!na)dfs(va+1,vb,2);
        else fanhui=1,dfs(va,vb,3);
        return ;
    }
    else if(d==2){
        int w=x+y;
        int va=(*upper_bound(q2[w].begin(),q2[w].end(),x))-1,vb;
        vb=w-va;
    //    printf("%d %d
",va,vb);
        //if(va==4&&vb==2){
        //    printf("%d %d
",x,y);while(1);
        //}
        if(org==d&&sx+sy==w&&sx>=x&&sx<=va){
            cishu++;
            if(cishu!=1){
                ans+=abs(sx-x);secs=1;return ;
            }
        }
        ans+=abs(va-x)+1;
        int na=0,nb=0;
        if(ditu[mp(va+1,vb)])na=1;
        if(ditu[mp(va,vb-1)])nb=1;
        if(na&&!nb)dfs(va,vb-1,3);
        else if(nb&&!na)dfs(va+1,vb,1);
        else fanhui=1,dfs(va,vb,4);
        return ;
    }
    else if(d==3){
        int w=x-y+m+1;
        int va=(*--upper_bound(q1[w].begin(),q1[w].end(),x))+1,vb;
        vb=va-w+m+1;
    //    printf("%d %d
",va,vb);
        //if(va==4&&vb==2){
        //    printf("%d %d
",x,y);while(1);
        //}
        if(org==d&&sx-sy+m+1==w&&sx<=x&&sx>=va){
            cishu++;
            if(cishu!=1){
                ans+=abs(sx-x);secs=1;return ;
            }
        }
        ans+=abs(va-x)+1;
        int na=0,nb=0;
        if(ditu[mp(va-1,vb)])na=1;
        if(ditu[mp(va,vb-1)])nb=1;
        if(na&&!nb)dfs(va,vb-1,2);
        else if(nb&&!na)dfs(va-1,vb,4);
        else fanhui=1,dfs(va,vb,1);
        return ;
    }
    else if(d==4){
        int w=x+y;
        int va=(*--upper_bound(q2[w].begin(),q2[w].end(),x))+1,vb;
        vb=w-va;
    //    printf("%d %d
",va,vb);
        //if(va==4&&vb==2){
        //    printf("%d %d
",x,y);while(1);
        //}
        if(org==d&&sx+sy==w&&sx<=x&&sx>=va){
            cishu++;
            if(cishu!=1){
                ans+=abs(sx-x);secs=1;return ;
            }
        }
        ans+=abs(va-x)+1;
        int na=0,nb=0;
        if(ditu[mp(va-1,vb)])na=1;
        if(ditu[mp(va,vb+1)])nb=1;
        if(na&&!nb)dfs(va,vb+1,1);
        else if(nb&&!na)dfs(va-1,vb,3);
        else fanhui=1,dfs(va,vb,2);
        return ;
    }
}
int main(){
    n=read();m=read();k=read();
    for(int i=1,x=0,y=0;i<=k;i++){
        x=read();y=read();
        q1[x-y+m+1].push_back(x);q2[x+y].push_back(x);
        ditu[mp(x,y)]=1;
    }
    F(j,0,m+1){
        q1[-j+m+1].push_back(0);
        q1[n+1-j+m+1].push_back(n+1);
        q2[j].push_back(0);
        q2[n+1+j].push_back(n+1);
        ditu[mp(0,j)]=1;ditu[mp(n+1,j)]=1;
    }
    F(i,0,n+1){
        q1[i+m+1].push_back(i);
        q1[i-m-1+m+1].push_back(i);
        q2[i].push_back(i);
        q2[i+m+1].push_back(i);
        ditu[mp(i,0)]=1;ditu[mp(i,m+1)]=1;
    }
    F(i,0,(n+m+2)){
        sort(q1[i].begin(),q1[i].end());sort(q2[i].begin(),q2[i].end());
    }
    sx=read();sy=read();
    string ch;cin>>ch;
    if(ch=="SW")org=2;
    else if(ch=="SE")org=1;
    else if(ch=="NW")org=3;
    else if(ch=="NE")org=4;
//    printf("%d
",org);
//    pf(ditu[mp(1,10)]);
    dfs(sx,sy,org);
    if(fanhui==1)ans>>=1;
    printf("%lld",ans);
}
il int read(){
    int s=0,f=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
    return f?-s:s;
}
/*
g++ 1.cpp -g
./a.out
10 9 10
1 8
6 9
3 6
4 3
10 5
3 4
6 1
10 2
9 8
7 6
10 1 SW
*/
View Code
Informatik verbindet dich und mich. 信息将你我连结。
原文地址:https://www.cnblogs.com/seamtn/p/11235605.html