GDUT ACM Training 2019 (矩阵快速幂,贪心,优先队列实现dijkstra,)

A. Apple Trees

time limit per test 1.0 s
memory limit per test 256 MB
input standard input
output standard output
In the beginning God created the heaven and the earth, the next five days God created the light, the water, the sky, the land, the trees and the living creatures, and on the sixth day he formed a man from the dust of the ground, called Adam. Afterwards, God took one of the man’s ribs and made a woman from the rib, called Eve. Adam and Eve lived in peace and harmony in the land, until God told them they should not take any apple from the only apple tree in Earth (at that moment, in year 0).
How they disobeyed God is a story from another day, now we are interested in how apple trees population increased over all those years. Apple trees are very interesting because their cycle of life is the following: first an apple fall into the ground and immediately a new apple tree blooms, from this moment we consider this as an apple tree, exactly ten years later the tree is full-grown and it starts to generate apples, from here every ten years the tree generates f(x) apples, where and x is the age of the tree, note that x will be always be a multiple of 10. Every apple generated from a tree will fall into the ground and generate a new tree, finally every apple tree dies exactly at the age of 45.
Now we want to know how many apple trees will be living on Earth after n years of the creation. At year 0 the apple tree created by God was not full-grown (this happened 10 years later).

Input

The input consists of only one integer n (0 ≤ n ≤ 1015) - the number of years after the creation of the Earth including Adam, Eve and the first apple tree.

Output

Print a single integer - the number of apple trees on Earth at the end of the n - th year after the creation of Earth, as this number can be very big print it modulo 109 + 7

Examples
input

9

output

1

input

10

output

17

input

44

output

77328

input

45

output

77327

Note

In the first case, at 9th year there was on Earth only the apple tree that God first created.
In second case we have that in the 10th year the first apple tree was full-grown and 16 apples that belonged to that tree made new 16 trees, therefore there were 17 trees.
In fourth case, we have that at year 45 the first apple tree died, so it doesn’t count anymore.

题目大意:

有一棵苹果树,第十年生16个,第二十年生9个,第三十年生4个,第四十年生1个,在45年时死去。给你一个时间,问这年一共有多少个苹果树。

题目思路:

矩阵快速幂。
推一下可以发现:
n=n/10;
f[n]=16*f[n-1]+9*f[n-2]+4*f[n-3]+f[n-4]+f[n-5]; n%10<5
f[n]=16*f[n-1]+9*f[n-2]+4*f[n-3]+f[n-4]; n%10>=5
16 9 4 1 0       f[n-1]       f[n]
1 0 0 0 0        f[n-2]       f[n-1]
0 1 0 0 0   ✖   f[n-3]   =  f[n-2]
0 0 1 0 0         f[n-4]      f[n-3]
0 0 0 1 0       f[n-5]     f[n-4]
F[n]=(矩阵相乘)n
用矩阵快速幂即可求解
初始矩阵
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
第一列为 f [n],f[n-1],f[n-2],f[n-3],f[n-4];

#include<iostream>
#define ll long long

using namespace std;

ll ans[5][5], change[5][5];

void mul(ll a[5][5], ll b[5][5]){
    ll c[5][5];
    ll d[5][5];
    for(int i=0; i<5; ++i){
        for(int j=0; j<5; ++j){
            c[i][j] = a[i][j];
            d[i][j] = b[i][j];
            a[i][j] = 0;
        }
    }
    for(int i=0; i<5; ++i){
        for(int j=0; j<5; ++j){
            for(int k=0; k<5; ++k){
                a[i][j]=(a[i][j]+c[i][k]*d[k][j])%1000000007;
            }
        }
    }
}

int main(){
    ll n;
    cin >> n;
    change[0][0] = 16;
    change[0][1] = 9;
    change[0][2] = 4;
    change[0][3] = 1;
    change[1][0] = 1;
    change[2][1] = 1;
    change[3][2] = 1;
    change[4][3] = 1;
    ans[0][0]=1;
    ans[1][1]=ans[2][2]=ans[3][3]=ans[4][4]=1;
    int p=n%10;
    n/=10;
    ll asd=0;
    //矩阵快速幂
    while(n){
        if(n&1) mul(ans,change);
        mul(change,change);
        n >>= 1;
        asd=ans[4][0];
}
    ll outans=asd+ans[0][0]+ans[1][0]+ans[2][0]+ans[3][0];
    if(p >= 5) outans-=asd;
    outans%=1000000007;
    cout<<outans<<endl;
}

F. UN Finals

time limit per test 0.5 s
memory limit per test 256 MB
input standard input
output standard output
The UN finals are here!, the coaches/ex-coaches team is creating a new exciting contest to select which teams will compete in the Colombian finals. Ivan said: the rules are clear, the only limitation to enroll teams in the Colombian finals is to pick a maximum of k teams per career. A team can be labeled with career X if there is no career Y such that more team members are enrolled in career Y than in career X. Finally, each team consists of three students (as usual).
Someone in the UN campus (UN finals are pretty popular) said, hey you guys should pick the teams careers in such a way that it maximizes the number of enrolled teams. Diego said: ah that is too easy. You will prove Diego right (or wrong). Given the description of the teams, output the maximum number of teams that can be enrolled in the Colombian finals.

Input

The first line is n (1 ≤ n ≤ 100) - the number of teams that registered to participate in the UN finals.
Next n lines contains each the information from each team, that is, there will be three strings per team (one per team member) separated by a single space. Each string consists of distinct upper case letters which represent the careers that a team member is studying (UN students love to study multiple careers).
The last line contains an integer k (1 ≤ k ≤ n) - the maximum allowed number of teams per career.

Output

Print a single integer - the maximum number of teams that can be enrolled.

Example
input

5
A ABC B
C C C
B B B
A A A
C AC CB
2

output

5

Note

In the first example first and fourth team can represent career A, second and fifth team can represent career C and third can represent team B.

题目大意:

有n个队伍,每个队伍有三个人每个人掌握A~Z中任意的技能。每个队伍能选择他们其中最擅长的技能中的一个。每个技能最多能选k支队伍,问有最多多少支队伍选择技能。(当时读错题QAQ,读成只要有一个人会就可以选)

题目思路:

将每个队伍可选择的技能提取出来,再对其大小进行排序,从小到大选择技能,并记录这个技能选择的次数。(技能在读取时也是已经按从小到大排过序了)

代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll M=110;
ll id[M],n,cnt_career[M],k;
vector<ll> label[M];  //第i个队伍,可以选择多少技能
bool cmp(ll x,ll y){
	return label[x].size()<label[y].size();
}
int main(){
	scanf("%lld",&n);
	for(ll i=0;i<n;i++){
		string x[3];
		ll cnt_al[26],max_al=0;
		memset(cnt_al,0,sizeof(cnt_al));
		cin>>x[0]>>x[1]>>x[2];
		for(ll j=0;j<3;j++)
			for(ll p=0;p<x[j].size();p++){
				cnt_al[x[j][p]-'A']++;  
				max_al=max(max_al,cnt_al[x[j][p]-'A']);
			}
		for(ll j=0;j<26;j++)
			if(cnt_al[j]==max_al)
				label[i].push_back(j);
	}
	cin>>k;
	for(ll i=0;i<n;i++)
		id[i]=i;
	sort(id,id+n,cmp);  //排序后记住id
	ll ans=0;
	for(ll i=0;i<n;i++){
		ll u=id[i],j=0;
		while(j<label[u].size() && cnt_career[label[u][j]]==k)
			j++;
		if(j<label[u].size()){
			ans++,cnt_career[label[u][j]]++;//记录技能选择了几次
		}
	}
	cout<<ans;
	return 0;
}

J. Jinping Trains

time limit per test 1.0 s
memory limit per test 256 MB
inputs tandard input
output standard output
Metr Pitrichev attended the 2018 ACM-ICPC World Finals in Beijing, China. Now that he finished streaming the contest he wants to travel from Beijing to Shanghai by train (he likes trains).
There are n (2 ≤ n ≤ 500) train stations in China and there are m (n - 1 ≤ m ≤ 500) train routes. Each train route consist of:
u (1 ≤ u ≤ n): Station where the train starts.
v (1 ≤ v ≤ n, v ≠ u): Station where train goes.
t (1 ≤ t ≤ 1000): Number of minutes it takes the train to go from station u to station v. So, if the train departs from u at minute x, it will arrive to v at minute x + t.
c (1 ≤ c ≤ 1000): Cost of taking the train (In RMB, the Chinese currency).
f (1 ≤ f ≤ 10): Frecuency of the train, in minutes.
s (0 ≤ s < f): Minute in which the first train leaves, so a trains leaves at each of these minutes: s, s + f, s + 2f, …
In order for Metr to take a train that leaves at time x that goes from station a to station b, he must have been in station a at time x - 1.
Beijing railway station is station number 1 and Shanghai railway station is station number n. Metr arrived at Beijing railway station at time 0. Being very smart, Metr will take best route and arrive to Shanghai as early as possible and if there are multiple ways to arrive as early as possible he will spend as little money as possible. There is always at least one way to go from station 1 to station n.

Input

The first line of input contains two integers n and m.
Each of the following m lines describes a train route with 6 space separated integers: u, v, t, c, f and s.

Output

Print one line with two integers separated by a single space - the time Metr reaches his destination and the total cost of the trip (In RMB), respectively.

Example
input

4 5
1 2 1 3 5 0
2 4 5 4 5 0
1 3 1 5 5 0
1 3 2 4 10 1
3 4 5 8 5 0

output

10 12

Note

In the example:
If Meter takes the first route and then the second route, he will arrive in 15 minutes and spend 7 RMB.
If Meter takes the third route and then the fifth route, he will arrive in 15 minutes and spend 13 RMB.
If Meter takes the fourth route and then the fifth route, he will arrive in 10 mitues and spend 12 RMB.

题目大意:

给出列车启动的车站,列车进的站,列车从U站到V站所需的分钟数,乘火车的费用,列车频率,第一列火车离开的分钟数。
算出最省时间时的时间和成本。(如果有多种,选成本最低的)

题目思路:

优先队列实现dijkstra。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=500+5;
struct node{
	int v,t,c,f,s;
	node(int _v=0,int _t=0,int _c=0,int _f=0,int _s=0):v(_v),t(_t),c(_c),f(_f),s(_s){}
}t;
struct qnode{
	int now,t,c;
	qnode(int _now=0,int _t=0,int _c=0):now(_now),t(_t),c(_c){}
	bool friend operator <(qnode a,qnode b){  //先按时间,后按花费
		if(a.t!=b.t) return a.t>b.t;
		return a.c>b.c;
	}
}qt;
vector <node> edge[maxn];
int dis[maxn],Cost[maxn];
int n,m;
void dijkstra(){
	for(int i=2;i<=n;i++) dis[i]=INF;
	dis[1]=0;
	priority_queue <qnode> q;
	q.push(qnode(1,0,0));
	while(!q.empty()){
		qt=q.top();
		q.pop();
		for(int i=0;i<edge[qt.now].size();i++){
			int to=edge[qt.now][i].v;
			int time=edge[qt.now][i].t;
			int cost=edge[qt.now][i].c;
			int f=edge[qt.now][i].f;
			int s=edge[qt.now][i].s;
			while(qt.t>=s){
				s+=f;
			}
			int wait=s-qt.t;
			//cout<<"666 "<<wait<<endl;
			if(dis[to]>qt.t+wait+time){
				dis[to]=qt.t+wait+time;
				Cost[to]=qt.c+cost;
				q.push(qnode(to,dis[to],qt.c+cost));
			}
			else if(dis[to]==qt.t+wait+time && Cost[to]>qt.c+cost){
				dis[to]=qt.t+wait+time;
				Cost[to]=qt.c+cost;
				q.push(qnode(to,dis[to],qt.c+cost));
			}
		}
	} 
}
int main(){
	cin>>n>>m;
	while(m--){
		int u,v,t,c,f,s;
		cin>>u>>v>>t>>c>>f>>s;
		edge[u].push_back(node(v,t,c,f,s));
	}
	dijkstra();
	cout<<dis[n]<<" "<<Cost[n]<<endl;
}

G. Generating Texts

time limit per test 1.0 s
memory limit per test 512 MB
input standard input
output standard output
Lucko is a greedy boy that is looking for ways to gain some money, one easy way he has found is to invest in bets on different lotteries, but he knows that the probability of winning a lottery is really low, for this reason he decides to play on a new lottery called UN-lotto.
To play UN-lotto one chooses a string of length m, then the lottery generates a string of length n (n ≥ m) randomly, both strings are formed only by lower-case letters from the english alphabet. You win if the string you have chosen is a subsequence of the generated text by UN-lotto.
Formally, for a string s = s1s2…sn we say that sa1sa2…sam is a subsequence of s of length m if 1 ≤ a1 < a2 < … < am ≤ n. For example, suppose that n = 4 and m = 3 and Lucko chooses the string abc, some of the winning generated strings for him would be abcb, abbc and abzc, and some of the losing generated strings would be acba, azbz and zzzz
Good news for Lucko, information about this lottery has been leaked

  • The text is generated taking each letter randomly from a probability distribution.
  • The selection of the letter for each position in the text is independent.
  • The probability distribution of the letters was also leaked.
    Lucko has already chosen his string to play UN-lotto, help him using the leaked information to tell him which is his probability P / Q of winning. As Lucko only likes low integer numbers calculate the probability modulo 109 + 7, i.e., calculate
    在这里插入图片描述
Input

The first line of input contains 2 numbers n and m (1 ≤ m ≤ n ≤ 5000) — the length of the string generated by UN-lotto and the length of the string chosen by Lucko respectively.
The second line of input contains s — the string chosen by Lucko.
Next 26 lines contains each a pair of integers separated by spaces, i.e. the i-th line contains pi, qi, where corresponds to the probability of taking the i-th letter, being a the first letter, b the second letter and so on. For every i = 1, …, 26, 0 ≤ pi ≤ 1000, 1 ≤ qi ≤ 1000 and pi / qi is an irreducible fraction.
It is guaranteed that .

Output

Output one integer — the probability modulo 109 + 7 of Lucko winning UN-lotto with the string s.

Examples
input

5 1
a
1 1
0 1
… 24 more lines …

output

1

input

5 3
aaa
1 2
1 2
0 1
… 23 more lines …

output

500000004

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值