2017-11-7 NOIP模拟赛

1.数学老师的报复

#include<iostream>
#include<cstdio>
using namespace std;
int cnt;
short int f[55000000];
long long a,b,n;
long long qread(){
    long long i=0,j=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')j=-1;ch=getchar();}
    while(ch<='9'&&ch>='0')i=i*10+ch-'0',ch=getchar();
    return i*j;
}
int main(){
    freopen("attack.in","r",stdin);freopen("attack.out","w",stdout);
//    freopen("Cola.in","r",stdin);
    a=qread();b=qread();n=qread();
    cnt=2;f[1]=1;f[2]=1;
    while(1){
        cnt++;
        f[cnt]=(a*f[cnt-1]+b*f[cnt-2])%7;
        if(f[cnt]==1&&f[cnt-1]==1)break;
        if(cnt==n)break;
    }
    if(n<=cnt){cout<<f[n];return 0;}
    cnt-=2;
    long long ans=n%cnt;
    if(ans==0)ans=cnt;
    ans=f[ans];
    cout<<ans;
}
95分 找循环节
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,aa,bb;
struct matrix{    
    ll a[2][2];    
    matrix(){memset(a,0,sizeof(a));}    
    matrix(ll b[2][2])    {for(int i=0;i<2;i++)for(int j=0;j<2;j++)a[i][j]=b[i][j];}    
    matrix operator * (matrix b)    
    {        
        matrix ans;        
        for(int i=0;i<2;i++)            
            for(int j=0;j<2;j++)                
                for(int k=0;k<2;k++)                    
                    ans.a[i][j]=(ans.a[i][j]+a[i][k]*b.a[k][j])%7;        
        ans.a[0][0]%=7;        
        return ans;    
    }    
}S,T; 

inline ll read()
{    
    ll x=0,f=1;char c=getchar();    
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}    
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}    
    return x*f;
} 

int main()
{    
    freopen("attack.in","r",stdin);
    freopen("attack.out","w",stdout);
    while(scanf("%lld%lld%lld",&aa,&bb,&n)!=EOF)    
    {        
        n-=2;        
        if(n==-1)    {printf("1");return 0;}        
        ll temp[2][2]={{aa,1},{bb,0}};        T=temp;        
        ll temp2[2][2]={{1,1},{0,0}};        S=temp2;        
        while(n)        
        {            
            if(n&1)    S=S*T;            
            T=T*T;            
            n>>=1;        
        }        
        S.a[0][0]%=7;        
        printf("%lld",S.a[0][0]);    
    }
    return 0;
}
100分 矩阵快速幂

2.物理和生物老师的战争

#include<iostream>
#include<cstdio>
using namespace std;
int T,n,m;
double ans;
int main(){
    freopen("fseq.in","r",stdin);freopen("fseq.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        ans=0;
        scanf("%d%d",&n,&m);
        if(n<m){puts("0.000000");continue;}
        double d=1.0/(n+1.0);
        printf("%.6lf
",1.0-m*d);
    }
}
100分 打表找规律

3.化学竞赛的大奖

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define maxn 20010
#ifdef WIN32
#define PLL "%I64d"
#else
#define PLL "%lld"
#endif
using namespace std;
int n,m,num,head[maxn],Num,Head[maxn];
int dfn[maxn],low[maxn],cnt,belong[maxn],gnum,st[maxn],top;
long long w[maxn];
bool in[maxn];
vector<int>g[maxn];
int fa[maxn][22],dis[maxn][22],dep[maxn];
struct node{int to,pre,v;}e[400010],E[400010];
void Insert(int from,int to,int v){e[++num].to=to;e[num].v=v;e[num].pre=head[from];head[from]=num;}
void Insert2(int from,int to,int v){E[++Num].to=to;E[Num].v=v;E[Num].pre=Head[from];Head[from]=Num;}
void Tarjan(int u,int father){
    cnt++;
    dfn[u]=low[u]=cnt;st[++top]=u;in[u]=1;
    for(int i=head[u];i;i=e[i].pre){
        int v=e[i].to;
        if(v==father)continue;
        if(!dfn[v]){
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
        }
        else if(in[v])low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        gnum++;
        while(st[top]!=u){
            int x=st[top];top--;
            in[x]=0;
            belong[x]=gnum;
            g[gnum].push_back(x);
        }
        in[u]=0;
        belong[u]=gnum;
        g[gnum].push_back(u);
        top--;
    }
}
void dfs(int now,int father){
    dep[now]=dep[father]+1;
    fa[now][0]=father;
    for(int i=Head[now];i;i=E[i].pre){
        int to=E[i].to;
        if(to==father)continue;
        dis[to][0]=E[i].v;
        dfs(to,now);
    }
}
long long lca(int a,int b){
    long long res=0;
    if(dep[a]<dep[b])swap(a,b);
    for(int i=18;i>=0;i--)
        if(dep[fa[a][i]]>=dep[b])
            res+=dis[a][i],a=fa[a][i];
    if(a==b)return res;
    for(int i=18;i>=0;i--)
        if(fa[a][i]!=fa[b][i]){
            res+=dis[a][i],res+=dis[b][i];
            a=fa[a][i],b=fa[b][i];
        }
    res+=dis[a][0]+dis[b][0];
    return res;
}
int main(){
//    freopen("Cola.txt","r",stdin);
    freopen("prize.in","r",stdin);freopen("prize.out","w",stdout);
    scanf("%d%d",&n,&m);
    int x,y,z;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        Insert(x,y,z);
        Insert(y,x,z);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
        {Tarjan(i,i);}
    for(int con=1;con<=gnum;con++)//枚举每个国家 
        for(int i=0;i<g[con].size();i++){//枚举这个国家里的每个城市 
            int from=g[con][i];
            for(int j=head[from];j;j=e[j].pre){
                int to=e[j].to;
                if(belong[from]!=belong[to]){
                    Insert2(belong[to],belong[from],e[j].v);
                }
            }
        }
    dfs(1,1);
    for(int j=1;j<=18;j++){
        for(int i=1;i<=gnum;i++){
            fa[i][j]=fa[fa[i][j-1]][j-1];
            dis[i][j]=dis[i][j-1]+dis[fa[i][j-1]][j-1];
        }
    }
    for(int i=1;i<=gnum;i++){
        long long ans=0;
        for(int j=1;j<=gnum;j++){
            long long now=lca(i,j);
            ans=max(ans,now);
        }
        w[i]=ans;
    }
    for(int i=1;i<=n;i++){
        printf(PLL"
",w[belong[i]]);
    }
}
60分 Tarjan缩点+倍增
原文地址:https://www.cnblogs.com/thmyl/p/7798998.html