zoukankan      html  css  js  c++  java
  • 图论3 1011

    三角形

    有一个等边三角形,在每条边上等距离画n个点,(顶点上不画,把每条边分成n+1段),在这3n个点中选取3个点作为新三角形的顶点,求所有不同三角形的面积和。

    3n个点有各自的编号,两个三角形不同当且仅当选取编号集合不同,规定单位面积为边长每一段长度的等边三角形面积。

    答案对1e9+7取模

    1<=n<=1e9

    题解

    很容易分出两类:有两个点在同一边上,三点都在不同边。

    1.记有两个点的边为底边。可以得到

    $2*3sum_{x=1}^{n-1}x(n-x)*sum_{h=1}^{n}h$(顶点可以在两边选取,底边有三种

    $3n(n+1)(nsum_{x=1}^{n-1}x-sum_{x=1}^{n-1}x^{2})$

    $frac{n^{2}(n+1)(n^{2}-1)}{2}$

    2.在三边分别选边,记a,b,c为三点到所在边的左端点的距离

    $sum_{a=1}^{n}sum_{b=1}^{n}sum_{c=1}^{n}(n+1)^{2}-(n+1-a)b-(n+1-b)c-(n+1-c)a$

    $sum_{a=1}^{n}sum_{b=1}^{n}sum_{c=1}^{n}(n+1)^{2}-(n+1)(a+b+c)+ab+ac+bc$

    $(n+1)^{2}$与a,b,c无关,所以可以算得贡献为$n^{3}(n+1){2}$

    对于(a+b+c)可以考虑画出树形图,发现c从1-n的取值重复了$n^{2}$次,所以贡献为$frac{n^{3}(n+1)^{2}}{2}$,a,b,c并无本质区别,所以a+b+c的贡献为$frac{3n^{3}(n+1)^{2}}{2}$

    对于后面剩下的部分只看$(a+b)c$

    $(sum_{a=1}^{n}sum_{b=1}^{n}(a+b))*sum_{c=1}^{n}c$

    $frac{n^{3}(n+1)^{2}}{2}$

    对于$ab$可以用$sum_{c=1}^{n}(sum_{a=1}^{n}a*sum_{b=1}^{n}b)$计算或者可以根据a,b,c无本质区别直接对刚才的$(a+b)c$*3/2即可

    最后合并就是$frac{n^{2}(n+1)(n^{2}-1)}{2}+frac{n^{3}(n+1)^{2}}{4}$

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int mod=1000000007;
    const ll inv2=500000004;
    const ll inv4=250000002;
    ll n;
    ll ret=0,ans;
    
    int main(){
        freopen("triangle.in","r",stdin);
        freopen("triangle.out","w",stdout);
        scanf("%lld",&n);
        ans=n*n%mod*(n+1)%mod*(n*n%mod-1)%mod*inv2%mod;//有两个点在一条边 
        ans=(ans+n*n%mod*n%mod*(n+1)%mod*(n+1)%mod*inv4%mod)%mod;
        printf("%lld",(ans%mod+mod)%mod);
    }
    triangle

    速度限制

    题目描述

    题解

    考虑到v很小而且通过道路时间和速度有关,所以直接把dis多开一维记录到达i点速度为j的时候的最小时间。

    在最短路时,记录标点号和速度即可。可以看做分层图(按速度分层)。要求路径就直接记录前驱。

    代码挺简单,但是一开始没想到方法...

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxn=155;
    const int maxm=555;
    const double inf=40000000000000000L;
    int n,m,t;
    int cnt,head[maxn];
    double dis[maxn][maxm];
    pair<int,int> pre[maxn][maxm];
    int top,s[maxn];
    struct edge{
        int x,y,v,l,next;
    }e[maxn*maxn];
    
    template<class T>inline void read(T &x){
        x=0;int f=0;char ch=getchar();
        while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x = f ? -x : x ;
    }
    
    void add(int x,int y,int v,int l){
        e[++cnt]=(edge){x,y,v,l,head[x]};
        head[x]=cnt;
    }
    
    bool vis[maxn][maxm];
    void spfa(){
        queue<pair<int,int> > q;
        memset(dis,0x7f,sizeof(dis));
        q.push(make_pair(0,70));
        vis[0][70]=true;dis[0][70]=0;
        while(!q.empty()){
            int x=q.front().first,nowv=q.front().second;
            q.pop();
            vis[x][nowv]=false;
            for(int i=head[x];i;i=e[i].next){
                int y=e[i].y;
                if(!e[i].v){//没限速 
                    if(dis[y][nowv]>dis[x][nowv]+1.0*e[i].l/nowv){
                        dis[y][nowv]=dis[x][nowv]+1.0*e[i].l/nowv;
                        pre[y][nowv]=make_pair(x,nowv);
                        if(!vis[y][nowv]){
                            q.push(make_pair(y,nowv));
                            vis[y][nowv]=true;
                        }
                    }
                }
                else {//限速 
                    if(dis[y][e[i].v]>dis[x][nowv]+1.0*e[i].l/e[i].v){
                        dis[y][e[i].v]=dis[x][nowv]+1.0*e[i].l/e[i].v;
                        pre[y][e[i].v]=make_pair(x,nowv);
                        if(!vis[y][e[i].v]){
                            q.push(make_pair(y,e[i].v));
                            vis[y][e[i].v]=true;
                        }
                    }
                }
            }
        }
    }
    
    int main(){
        freopen("speed.in","r",stdin);
        freopen("speed.out","w",stdout);
        read(n);read(m);read(t);
        for(int i=1;i<=m;i++){
            int x,y,v,l;
            read(x);read(y);read(v);read(l);
            add(x,y,v,l);
        }
        spfa();
        pair<int,int> x=make_pair(t,0);
        double mx=inf;
        for(int i=0;i<=500;i++)
         if(dis[t][i]<mx)
          mx=dis[t][i],x.second=i;
        while(1){
            s[++top]=x.first;
            if(!x.first) break;
            x=pre[x.first][x.second];
        }
        for(int i=top;i;i--) printf("%d ",s[i]);
    }
    speed

    替换游戏

     题解

    对于60%的数据,直接建返图缩点跑拓扑就好了

    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const int maxn=100005;
    int n,m,k,Q;
    int cnt,head[maxn];
    int d[maxn];
    vector<int> g[maxn];
    int cur,dfn[maxn],low[maxn];
    bool flag[maxn];
    int top,s[maxn];
    int num,res[maxn],size[maxn];
    struct edge{
        int x,y,next;
    }e[maxn<<3];
    ll f[maxn];
    
    template<class T>inline void read(T &x){
        x=0;int f=0;char ch=getchar();
        while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x = f ? -x : x ;
    }
    
    void add(int x,int y){
        e[++cnt]=(edge){x,y,head[x]};
        head[x]=cnt;d[y]++;
    }
    
    void tarjan(int x){
        dfn[x]=low[x]=++cur;
        flag[x]=true;s[++top]=x;
        for(unsigned int i=0;i<g[x].size();i++){
            int y=g[x][i];
            if(!dfn[y]){tarjan(y);low[x]=min(low[x],low[y]);}
            else if(flag[y]) low[x]=min(low[x],dfn[y]);
        }
        if(dfn[x]==low[x]){
            ++num;
            int t;
            do{
                t=s[top--];
                res[t]=num;
                flag[t]=false;
                size[num]+=t;
            }while(t!=x);
        }
    }
    
    void topsort(){
        queue<int> q;
        for(int i=1;i<=num;i++)
         if(!d[i]) q.push(i),f[i]=size[i];
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=head[x];i;i=e[i].next){
                int y=e[i].y;
                if(f[y]<f[x]+size[y]) f[y]=f[x]+size[y];
                d[y]--;
                if(!d[y]) q.push(y);
            }
        }
    }
    
    void plana(){
        for(int i=1;i<=m;i++){
            int x,y;
            read(x);read(y);
            g[y].push_back(x);
        }
        for(int i=n;i>=k;i--) g[i].push_back(i-k);
        for(int i=0;i<=n;i++)
         if(!dfn[i]) tarjan(i);
        for(int i=0;i<=n;i++)
         for(unsigned int j=0;j<g[i].size();j++)
          if(res[i]!=res[g[i][j]]) add(res[i],res[g[i][j]]);
        topsort();
        read(Q);
        while(Q--){
            int x;read(x);
            printf("%lld
    ",f[res[x]]);
        }
    }
    
    int main(){
        freopen("substitution.in","r",stdin);
        freopen("substitution.out","w",stdout);
        read(n);read(m);read(k);
        plana();
    }
    /*
    11 3 12
    1 10
    10 1
    11 10
    */
    60
  • 相关阅读:
    iBatis——自动生成DAO层接口提供操作函数(详解)
    【Spring Boot项目】Win7+JDK8+Tomcat8环境下的War包部署
    MySQL使用小记
    DB迁移:从SQL Server 2005到MySQL
    【文章学习】监控网页卡顿、崩溃
    为什么执行x in range(y)如此之快
    python笔试题(三)
    python笔试题(二)
    python笔试题(-)
    rest-framework(2)
  • 原文地址:https://www.cnblogs.com/sto324/p/11656427.html
Copyright © 2011-2022 走看看