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
Your job is simple, for each task, you should output Fn module 109+7.
⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊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 , B, C, D, P, n.
1≤T≤200≤A,B,C,D≤1091≤P,n≤109
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤T≤200≤A,B,C,D≤1091≤P,n≤109
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("\n"); #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('\n'); } 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 (1≤i≤M) line connects port Ai and Bi (Ai≠Bi) 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)
The i-th (1≤i≤M) line connects port Ai and Bi (Ai≠Bi) 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 (2≤N≤100000) and M (0≤M≤200000), 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 (1≤Ai,Bi≤N) and the third representing the identification number Ci (1≤Ci≤1000000) of Weitian who occupies this shipping line.
For each test case,In the first line, two integers N (2≤N≤100000) and M (0≤M≤200000), 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 (1≤Ai,Bi≤N) and the third representing the identification number Ci (1≤Ci≤1000000) 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\n"); 100 else printf("%d\n",dis[n]); 101 //test(); 102 for(i=1;i<=n;i++) GG[i].clear(); 103 } 104 return 0; 105 }