• HDU 2254 奥运(矩阵+二分等比求和)


    奥运

    【题目链接】奥运

    【题目类型】矩阵+二分等比求和

    &题解:

    首先离散化城市,之后就是矩阵快速幂了,但让求的是A(t1)+A(t1+1)+...+A^(t2),我先想的是打表,但时间真的太慢了,之后网上查的二分等比求和,这样logn就可以求等比矩阵的前n项和了
    还有用二分等比求和时,矩阵最好用数组表示,尽量不用vector,我试了好几发,总是T,当然也有可能是我写的low了吧 - -

    &代码:

    #include <cstdio>
    #include <bitset>
    #include <iostream>
    #include <set>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <vector>
    using namespace std;
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N= 30 +9;
    
    struct Matrix
    {
    	int m[N][N];
    };
    Matrix I,ZZ;
    int n,m,M=2008;
    
    Matrix add(Matrix a,Matrix b)
    {
    	Matrix c;
    	for(int i=0;i<n;i++)
    		for(int j=0;j<n;j++)
    			c.m[i][j]=(a.m[i][j]+b.m[i][j])%M;
    	return c;
    }
    
    Matrix multi(Matrix a,Matrix b)
    {
    	Matrix c;
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			c.m[i][j]=0;
    			for(int k=0;k<n;k++)
    				c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%M;
    		}
    	}
    	return c;
    }
    Matrix power(Matrix A,ll n)
    {
    	Matrix ans=I;
    	while(n){
    		if(n&1)
    			ans=multi(ans,A);
    		A=multi(A,A);
    		n>>=1;
    	}
    	return ans;
    }
    
    Matrix sum(Matrix A,ll k)
    {
    	if(k<=0) return ZZ;
    	if(k==1) return A;
    //	cout<<"k="<<k<<endl;
    	Matrix t=sum(A,k/2);
    	Matrix cur=power(A,k/2+(k&1));
    	t=add(t,multi(t,cur));
    	if(k&1) t=add(t,cur);
    	return t;
    }
    int v1,v2,t1,t2;
    map<int,int> tb;
    int main()
    {
    	freopen("E:1.txt","r",stdin);
    	while(cin>>n){
    		Matrix gra;
    		//一定记得要初始化啊 矩阵I ZZ 和gra 
    		tb.clear();
    		for(int i=0;i<35;i++){
    			I.m[i][i]=1;
    			for(int j=0;j<35;j++){
    				ZZ.m[i][j]=0;
    				gra.m[i][j]=0;
    			}
    		}
    		int ct=0;
    		for(int i=0;i<n;i++){
    			int u,v;
    			cin>>u>>v;
    			if(tb[u]==0)
    				tb[u]=++ct;
    			if(tb[v]==0)
    				tb[v]=++ct;
    			gra.m[tb[u]-1][tb[v]-1]++;
    			gra.m[tb[u]-1][tb[v]-1]%=M;
    		}
    		cin>>m;
    		for(int i=0;i<m;i++){
    			cin>>v1>>v2>>t1>>t2;
    
    			if(!tb[v1]||!tb[v2]){
    				puts("0");
    			}
    			else{
    				Matrix an1=sum(gra,t2);
    				Matrix an2=sum(gra,t1-1);
    				//这块 处理的时候减1了 输入地图的时候也要减1啊
    				cout<<((an1.m[tb[v1]-1][tb[v2]-1]-an2.m[tb[v1]-1][tb[v2]-1])%M+M)%M<<endl;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    微软WP7本机数据库解决方案之Sqlite
    NSIS nsDialogs Plugin
    NSIS 的 Modern UI 教程
    C# Sqlite For WP7
    铁血规则:事件预订与取消预订[转]
    .NET FRAMEWORK2.0中的农历类
    DefWndProc/WndProc/IMessageFilter的区别
    经典正则表达式分析与收藏
    博客园怎么了?
    .net项目开发工具(最近更新V2.1.0.5)
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6655611.html
Copyright © 2020-2023  润新知