zoukankan      html  css  js  c++  java
  • HDU 6395 分段矩阵快速幂 HDU 6386 建虚点+dij

    http://acm.hdu.edu.cn/showproblem.php?pid=6395

    Sequence

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 1475    Accepted Submission(s): 539


    Problem Description
    Let us define a sequence as below

    F1F2Fn===ABCFn2+DFn1+Pn


      Your job is simple, for each task, you should output Fn module 109+7.
     
    Input
    The first line has only one integer T, indicates the number of tasks.

    Then, for the next T lines, each line consists of 6 integers, A , BCDPn.

    1T200A,B,C,D1091P,n109
     
    Sample Input
    2 3 3 2 1 3 5 3 2 2 2 1 4
     
    Sample Output
    36 24
     
    解析  p/n 不是定值不能直接矩阵快速幂  但是观察发现
    23 
     1     2   3   4   5   6   7   8   9  10  11  12  13...100   除数
     23  12  7   5   4   3   3   2    2   2   2   1    1 .... 0      商

        商的个数很少 我们可以 分段矩阵快速幂   怕超时 可以先打1e5的表    一开始以为要用逆元解决问题  真的智障了

    #include <bits/stdc++.h>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define all(a) (a).begin(), (a).end()
    #define fillchar(a, x) memset(a, x, sizeof(a))
    #define huan printf("
    ");
    #define debug(a,b) cout<<a<<" "<<b<<" "<<endl;
    using namespace std;
    typedef long long ll;
    const ll maxn=3,inf=0x3f3f3f3f,mod=1e9+7;
    bool Finish_read;
    template<class T>inline void read(T &x)
    {
        Finish_read=0;
        x=0;
        int f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')f=-1;
            if(ch==EOF)return;
            ch=getchar();
        }
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        x*=f;
        Finish_read=1;
    }
    template<class T>inline void print(T x)
    {
        if(x/10!=0)print(x/10);
        putchar(x%10+'0');
    }
    template<class T>inline void writeln(T x)
    {
        if(x<0)putchar('-');
        x=abs(x);
        print(x);
        putchar('
    ');
    }
    template<class T>inline void write(T x)
    {
        if(x<0)putchar('-');
        x=abs(x);
        print(x);
    }
    ll n,a,b,c,d,p;
    struct Matrix
    {
        ll m[maxn][maxn];
        Matrix()
        {
            memset(m,0,sizeof(m));
        }
        void init()
        {
            for(int i=0; i<maxn; i++)
                for(int j=0; j<maxn; j++)
                    m[i][j]=(i==j);
        }
        Matrix  operator +(const Matrix &b)const
        {
            Matrix c;
            for(int i=0; i<maxn; i++)
            {
                for(int j=0; j<maxn; j++)
                {
                    c.m[i][j]=(m[i][j]+b.m[i][j])%mod;
                }
            }
            return c;
        }
        Matrix  operator *(const Matrix &b)const
        {
            Matrix c;
            for(int i=0; i<maxn; i++)
            {
                for(int j=0; j<maxn; j++)
                {
                    for(int k=0; k<maxn; k++)
                    {
                        c.m[i][j]=(c.m[i][j]+(m[i][k]*b.m[k][j])%mod)%mod;
                    }
                }
            }
            return c;
        }
        Matrix  operator^(const ll &t)const
        {
            Matrix ans,a=(*this);
            ans.init();
            ll n=t;
            while(n)
            {
                if(n&1) ans=ans*a;
                a=a*a;
                n>>=1;
            }
            return ans;
        }
    };
    ll f[100010];
    pair<ll,ll> solve(ll x,ll y,ll z,ll m)
    {
        Matrix a,b,temp;
        b.m[0][0]=d;b.m[0][1]=c;b.m[0][2]=1;
        b.m[1][0]=1;b.m[2][2]=1;
        a.m[0][0]=x;
        a.m[1][0]=y;
        a.m[2][0]=z;
        temp=b^(m);
        temp=temp*a;
        return mp(temp.m[0][0],temp.m[1][0]);
    }
    int main()
    {
        int t;
        read(t);
        while(t--)
        {
            read(a);read(b);read(c);read(d);read(p);read(n);
            f[1]=a;f[2]=b;
            for(int i=3;i<=100000;i++)
                f[i]=(c*f[i-2]%mod+d*f[i-1]%mod+p/i)%mod;
            if(n<=100000)
                writeln(f[n]);
            else
            {
                ll l=100000;
                pair<ll,ll> pp(f[l],f[l-1]);l++;
                while(l<=n)
                {
                    ll temp=p/l;
                    if(temp==0)
                    {
                        pp=solve(pp.fi,pp.se,temp,n-l+1);
                        writeln(pp.fi);
                        break;
                    }
                    ll temp2=p/temp;
                    if(temp2>=n)
                    {
                        pp=solve(pp.fi,pp.se,temp,n-l+1);
                        writeln(pp.fi);
                        break;
                    }
                    else
                    {
                        pp=solve(pp.fi,pp.se,temp,temp2-l+1);
                        l=temp2+1;
                    }
                }
            }
        }
    }

    http://acm.hdu.edu.cn/showproblem.php?pid=6386

    Age of Moyu

    Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 2237    Accepted Submission(s): 683


    Problem Description
    Mr.Quin love fishes so much and Mr.Quin’s city has a nautical system,consisiting of N ports and M shipping lines. The ports are numbered 1 to N. Each line is occupied by a Weitian. Each Weitian has an identification number.

    The i-th (1iM) line connects port Ai and Bi (AiBi) bidirectionally, and occupied by Ci Weitian (At most one line between two ports).

    When Mr.Quin only uses lines that are occupied by the same Weitian, the cost is 1 XiangXiangJi. Whenever Mr.Quin changes to a line that is occupied by a different Weitian from the current line, Mr.Quin is charged an additional cost of 1 XiangXiangJi. In a case where Mr.Quin changed from some Weitian A's line to another Weitian's line changes to Weitian A's line again, the additional cost is incurred again.

    Mr.Quin is now at port 1 and wants to travel to port N where live many fishes. Find the minimum required XiangXiangJi (If Mr.Quin can’t travel to port N, print 1instead)
     
    Input
    There might be multiple test cases, no more than 20. You need to read till the end of input.

    For each test case,In the first line, two integers N (2N100000) and M (0M200000), representing the number of ports and shipping lines in the city.

    In the following m lines, each contain three integers, the first and second representing two ends Ai and Bi of a shipping line (1Ai,BiN) and the third representing the identification number Ci (1Ci1000000) of Weitian who occupies this shipping line.
     
    Output
    For each test case output the minimum required cost. If Mr.Quin can’t travel to port N, output 1 instead.
     
    Sample Input
    3 3 1 2 1 1 3 2 2 3 1 2 0 3 2 1 2 1 2 3 2
     
    Sample Output
    1 -1 2
     

    解析 这题标程有些错误 而且是原题 既然标程是错的 也就不用按照 题解来写了 感觉现在最靠谱的思路就是 建虚点了 边权相同且相邻的点 建立一个虚点x

    其他点到x距离为1的单向边 x到其他点距离为0单向边 把原来的去掉 跑最短路就是答案。这道题真是服了。。。

      1 #include <bits/stdc++.h>
      2 #define Pii pair<int,int>
      3 using namespace std;
      4 typedef long long ll;
      5 const int maxn=1e5+5;
      6 const int maxm=2e5+5;
      7 const int maxnn=1e6+5;
      8 const int inf=2147483647;
      9 vector<int> GG[maxn];
     10 int from[maxm],to[maxm],c[maxm];
     11 int n,cnt,nowc,dis[maxnn];             //cnt:n+虚点数
     12 bool v[maxm],vis[maxnn];
     13 struct node{
     14     int d,x;
     15     bool operator < (const node& b) const
     16     {return d>b.d;}
     17 };
     18 priority_queue<node> Q;
     19 int _first[maxnn],_tip[maxnn],_w[maxnn],_next[maxnn],edge;
     20 inline void dijk()
     21 {
     22     int i,u,vv,len,num;
     23     node tmp;
     24     for(i=1;i<=cnt;i++) dis[i]=inf;
     25     dis[1]=0;
     26     Q.push((node){0,1});
     27     while(!Q.empty())
     28     {
     29         tmp=Q.top();
     30         Q.pop();
     31         u=tmp.x;
     32         if(vis[u]==true) continue;
     33         vis[u]=true;
     34         num=_first[u];
     35         while(num!=-1)
     36         {
     37             vv=_tip[num];
     38             if(dis[u]!=inf&&dis[vv]>dis[u]+_w[num])
     39             {
     40                 dis[vv]=dis[u]+_w[num];
     41                 Q.push((node){dis[vv],vv});
     42             }
     43             num=_next[num];
     44         }
     45     }
     46     return;
     47 }
     48 inline void dfs(int x)
     49 {
     50     //add(x,cnt,1);
     51     _tip[++edge]=cnt;
     52     _w[edge]=1;
     53     _next[edge]=_first[x];
     54     _first[x]=edge;
     55 
     56     //add(cnt,x,0);
     57     _tip[++edge]=x;
     58     _w[edge]=0;
     59     _next[edge]=_first[cnt];
     60     _first[cnt]=edge;
     61 
     62     int i,len=GG[x].size(),num;
     63     for(i=0;i<len;i++)
     64     {
     65         num=GG[x][i];
     66         if(c[num]==nowc&&!v[num])
     67         {
     68             v[num]=true;
     69             if(from[num]==x) dfs(to[num]);
     70             else dfs(from[num]);
     71         }
     72     }
     73     return;
     74 }
     75 int main()
     76 {
     77     int i,m;
     78     while(scanf("%d%d",&n,&m)==2)
     79     {
     80         edge=0;
     81         cnt=n;
     82         memset(v,0,sizeof(v));
     83         memset(vis,0,sizeof(vis));
     84         memset(_first,-1,sizeof(_first));
     85         for(i=1;i<=m;i++)
     86         {
     87             scanf("%d%d%d",&from[i],&to[i],&c[i]);
     88             GG[from[i]].push_back(i);
     89             GG[to[i]].push_back(i);
     90         }
     91         for(i=1;i<=m;i++)
     92             if(!v[i])
     93             {
     94                 cnt++;
     95                 nowc=c[i];
     96                 dfs(from[i]);
     97             }
     98         dijk();
     99         if(dis[n]==inf) printf("-1
    ");
    100         else printf("%d
    ",dis[n]);
    101         //test();
    102         for(i=1;i<=n;i++) GG[i].clear();
    103     }
    104     return 0;
    105 }
    View Code

    转自  https://blog.csdn.net/jerry99s/article/details/81664117

     
  • 相关阅读:
    Ubuntu Linux Matlab 安装 中文乱码 桌面启动器 Could not find the main class: java/splash.png. 终端terminal 直接运行 matlab
    Ubuntu Linux 官网 u盘安装 u盘系统 图文教程
    从google map google earth获得大图 方法总结
    论文查重网址
    [ZZ] Computer Science Conference Rankings
    Ubuntu linux 信使 iptux Window 飞鸽 ipmsg 飞秋 feiq 文件传输
    Ubuntu Linux Matlab mex
    Ubuntu Dell OptiPlex 990 Intel Gigabit CT Desktop Adapter网卡驱动安装
    C++的File类文件操作
    GIS软件比较
  • 原文地址:https://www.cnblogs.com/stranger-/p/9476083.html
Copyright © 2011-2022 走看看