zoukankan      html  css  js  c++  java
  • Comet OJ

    A

    code:

    #include <cstdio> 
    #include <algorithm>    
    #define N 1000000 
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin)   
    using namespace std; 
    ll f[N],g[N];      
    int main() 
    {    
        // setIO("input");  
        int i,j;     
        f[1]=1,f[2]=1,g[2]=2;        
        ll x;  
        scanf("%lld",&x);    
        if(x<=2) { printf("%lld
    ",x+1);      return 0; }    
        for(i=3;;++i) 
        {
            f[i]=g[i-1]/2;      
            g[i]=g[i-1]+f[i];      
            if(g[i]>x) 
            {
                printf("%d
    ",i); 
                return 0;  
            } 
        }
        return 0;
    }
    

      

    B

    推式子发现是二次函数的形式,套用二次函数公式好了. 

    code: 

    #include <cstdio> 
    #include <algorithm> 
    #include <cstring> 
    #include <cmath>     
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    int main() 
    { 
        // setIO("input");      
        int i,j;   
        double l,r,L,R;  
        scanf("%lf%lf%lf%lf",&l,&r,&L,&R);       
        double q=(L+R)*0.5;      
        double sl=(l+q)*0.5;      
        sl=max(l,min(sl,r));                                  
        printf("%.4f
    ",max(0.0000,(double)(sl-l)/(r-l)*(q-sl)));   
        return 0;    
    }
    

      

    C

    感觉这个比 B 简单啊,直接枚举就好了. 

    code: 

    #include <cstdio>  
    #include <map> 
    #include <vector>   
    #include <set>   
    #include <cstring> 
    #include <algorithm>   
    #define ll long long 
    #define mod 998244353   
    #define N 100006 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;  
    int fac[N],inv[N];  
    int qpow(int x,ll y)  
    {
        int tmp=1;   
        for(;y;y>>=1,x=(ll)x*x%mod) 
            if(y&1) tmp=(ll)tmp*x%mod;  
        return tmp;  
    } 
    int INV(int x) { return qpow(x,mod-2); }     
    void init() 
    {
        fac[0]=inv[0]=1;
        int i,j;    
        for(i=1;i<N;++i) fac[i]=(ll)fac[i-1]*i%mod,inv[i]=INV(fac[i]);   
    }
    int C(int x,int y) 
    {
        if(x<0||y<0||x<y) return 0;   
        return (ll)fac[x]*inv[y]%mod*inv[x-y]%mod;  
    }
    int main() 
    {
        // setIO("input");        
        init();  
        int n,x,y,ans=0,i,j,det;          
        scanf("%d%d%d",&n,&x,&y);   
        det=(ll)x*INV(y)%mod;               
        for(i=1;i<=n;++i) 
        { 
            int tp=(ll)C(n,i)*qpow(det,1ll*i*(i-1)/2)%mod;    
            (ans+=(ll)C(n,i)*qpow(det,(ll)i*(i-1)/2)%mod)%=mod;             
        }
        printf("%d
    ",(ans+1)%mod);  
        return 0;  
    }         
    

      

    D

    枚举中心点,容斥原理算一算 

    code: 

    #include <bits/stdc++.h>  
    #define N 4010 
    #define ll long long 
    #define mod 998244353    
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;  
    int edges,now,n;  
    int hd[N<<1],to[N<<2],nex[N<<2],cnt[N<<1][N],sum[N],bin[N],ans[N];      
    void add(int u,int v) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;    
    }
    void dfs(int u,int ff,int d) 
    {
        if(u<=n) ++sum[d], ++cnt[now][d];        
        for(int i=hd[u];i;i=nex[i]) if(to[i]!=ff) dfs(to[i], u, d+1); 
    }
    int main() 
    {  
        // setIO("input");  
        int i,j;  
        scanf("%d",&n);   
        bin[0]=1; 
        for(i=1;i<=n;++i) bin[i]=bin[i-1]*2%mod; 
        for(i=1;i<n;++i) 
        {
            int u,v; 
            scanf("%d%d",&u,&v);    
            add(u,i+n),add(i+n,u);
            add(i+n,v),add(v,i+n);           
        }  
        for(i=1;i<=2*n;++i) 
        {
            now=0;   
            for(j=hd[i];j;j=nex[j]) ++now, dfs(to[j],i,1);         
            int re=(i<=n);     
            for(j=1;j<n;++j) 
            {
                int mdl=bin[sum[j]]-1;   
                for(int k=1;k<=now;++k) 
                {
                    (mdl+=mod-bin[cnt[k][j]]+1)%=mod;   
                }    
                (ans[j]+=(ll)mdl*bin[re]%mod)%=mod;    
                re+=sum[j];   
            }
            memset(sum,0,sizeof sum);   
            for(j=1;j<=now;++j) memset(cnt[j], 0, sizeof cnt[j]);    
        }
        for(i=1;i<n;++i) 
            printf("%d
    ",(ans[i]+mod)%mod);    
        return 0;   
    }
    

      

    E

    我们发现图形是一个基环数森林.   

    如果是树形结构的话十分方便.   

    而我们可以将问题简化为如何处理环.    

    显然,我们要枚举起点,并将起点出发的边断开,然后维护一圈 $ans_{i}=A_{i}+B_{i} imes ans_{i-1}$.   

    这个满足结合律,用线段树维护即可. 

    code: 

    #include <cstdio> 
    #include <algorithm>        
    #include <cstring>        
    #include <vector> 
    #include <map>   
    #include <queue>   
    #define ll long long    
    #define N 200008   
    #define mod 998244353  
    #define setIO(s) freopen(s".in","r",stdin)  
    using namespace std;    
    int A[N],B[N],ans[N];      
    int qpow(int x,int y) 
    {
        int tmp=1; 
        for(;y;y>>=1,x=(ll)x*x%mod) 
            if(y&1) tmp=(ll)tmp*x%mod; 
        return tmp;   
    }
    int INV(int x) { return qpow(x,mod-2); } 
    namespace seg
    {     
        #define lson now<<1 
        #define rson now<<1|1    
        struct node 
        {
            int a,b;          
            node() { a=b=0; }
            node operator+(const node &t) const 
            {    
                node c;   
                c.a=(ll)(t.a+(ll)t.b*a%mod)%mod;   
                c.b=(ll)t.b*b%mod;    
                return c;       
            }         
        }s[N<<2];   
        void build(int l,int r,int now) 
        {
            if(l==r) 
            {       
                s[now].a=A[l];  
                s[now].b=B[l];   
                return;  
            }  
            int mid=(l+r)>>1;    
            build(l,mid,lson),build(mid+1,r,rson);    
            s[now]=s[lson]+s[rson]; 
        } 
        node query(int l,int r,int now,int L,int R) 
        {
            if(l>=L&&r<=R) return s[now];    
            int mid=(l+r)>>1;  
            if(L<=mid&&R>mid) return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R); 
            else if(L<=mid) return query(l,mid,lson,L,R); 
            else return query(mid+1,r,rson,L,R);    
        }       
        #undef lson 
        #undef rson  
    };   
    int n;               
    int deg[N],p[N],go[N],seq[N],id[N],s[N];                        
    queue<int>q;                                        
    void solve_tree() 
    {    
        int i,j;      
        for(i=1;i<=n;++i) if(!deg[i]) q.push(i);    
        while(!q.empty()) 
        {
            int u=q.front();q.pop();          
            int v=go[u];    
            --deg[v];    
            p[v]=(ll)(p[v]+(ll)(1-p[v]+mod)*s[u]%mod*p[u]%mod)%mod;    
            if(deg[v]==0) q.push(v);      
        }
    }
    void solve_circle(int x) 
    {          
        int i,j;   
        int t=go[x],top=0;      
        seq[++top]=x;                       
        while(t!=x) seq[++top]=t,t=go[t];    
        for(i=1;i<=top;++i) seq[top+i]=seq[i];                                  
        for(i=1;i<=top;++i) id[seq[i]]=i,deg[seq[i]]=0;       
        for(i=2;i<=(top<<1);++i) 
        {
            A[i]=p[seq[i]];          
            B[i]=(ll)(1-p[seq[i]]+mod)*s[seq[i-1]]%mod;            
        }
        A[1]=A[top+1],B[1]=B[top+1];    
        seg::build(1,top<<1,1);                            
        for(i=1;i<=top;++i) 
        {
            int u=seq[i];           
            seg::node an=seg::query(1,top<<1,1,i+2,i+top);                          
            ans[u]=(ll)((ll)an.b*p[seq[i+1]]%mod+an.a)%mod;    
        }
    }
    int main() 
    { 
        // setIO("input");         
        int i,j; 
        scanf("%d",&n);  
        for(i=1;i<=n;++i) 
        { 
            int x,y;   
            scanf("%d%d",&x,&y);        
            p[i]=(ll)x*INV(y)%mod;   
        }
        for(i=1;i<=n;++i) scanf("%d",&go[i]),++deg[go[i]];      
        for(i=1;i<=n;++i) 
        {
            int x,y;   
            scanf("%d%d",&x,&y);     
            s[i]=(ll)x*INV(y)%mod;   
        }
        solve_tree();      
        for(i=1;i<=n;++i)  if(!deg[i]) ans[i]=p[i];  
        for(i=1;i<=n;++i) 
        {
            if(deg[i]) solve_circle(i); 
            printf("%d ",ans[i]);   
        }
        return 0;   
    }
    

      

  • 相关阅读:
    “Hello World”团队第一周博客汇总
    SFTP服务器之创建普通用户
    软工2017第五周——个人PSP
    "Hello world!"团队第一次会议
    软工2017第四周作业--结对编程之四则运算
    软工2017第四周作业结对编程——个人psp
    软工2017第四周作业结对编程——单元测试
    软工2017第四周作业——代码规范
    软工第三次作业——个人PSP
    iOS原生和React-Native之间的交互1
  • 原文地址:https://www.cnblogs.com/guangheli/p/12309968.html
Copyright © 2011-2022 走看看