HDU-2817 A sequence of numbers(快速幂取模)
题意:给一个数列的前三项,该数列可能是等比或等差,求第k项
题解:快速幂取模
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define mod 200907
using namespace std;
long long a, b, c;
long long k;
long long Mode(long long a, long long b, long long mode)
{
long long sum = 1;
while (b) {
if (b & 1) {
sum = (sum * a) % mode;
b--;
}
b /= 2;
a = a * a % mode;
}
return sum;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%lld %lld %lld %lld", &a, &b, &c, &k);
long long res;
if(b-a == c-b && b!=a){
res = (a%mod+(((k-1)%mod)*((b-a)%mod))%mod)%mod;
}
else{
res = ((a%mod)*(Mode(b/a, k-1, mod)%mod))%mod;
}
printf("%lld\n", res);
}
return 0;
}
HDU-2818 Building Block(带权并查集)
题意:有N堆牌,初始值为1,有两种操作,M X Y 把X所在的牌堆整体放在Y所在的牌堆上,C X 查询X下面有多少张牌
题解:带权并查集,可以看作每张牌到底端的距离
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int fa[30010];
int dis[30010];
int num[30010];
int Q;
int Find(int x){
if(x != fa[x]){
int t = fa[x];
fa[x] = Find(t);
dis[x] += dis[t];
}
return fa[x];
}
int main(){
for(int i = 0; i<=30010; i++){
//dis[i] = 1;
fa[i] = i;
num[i] = 1;
}
scanf("%d", &Q);
while(Q--){
char ch[3]; int x, y;
scanf("%s", ch);
if(ch[0] == 'C'){
scanf("%d", &x);
int rootx = Find(x);
//cout<<" "<<rootx<<" "<<dis[x]<<endl;
printf("%d\n", dis[x]);
}
else{
scanf("%d %d", &x, &y);
int rootx = Find(x);
int rooty = Find(y);
if(rootx == rooty) continue;
fa[rootx] = rooty;
dis[rootx] = num[rooty];
num[rooty] += num[rootx];
}
}
return 0;
}
HDU-2822 Dogs(bfs+优先队列)
题意:给一个矩阵,求最短的时间从起点走到终点。.一次花费1单位时间,X不花费时间
题解:因为地图的权值是不等的,因此用一个优先队列进行bfs
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n, m;
int sx, sy, ex, ey;
char ma[1010][1010];
int vis[1010][1010];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
struct node{
int x, y;
int time;
friend bool operator < (const node &a, const node &b){
return a.time>b.time;
}
};
priority_queue<node> que;
int bfs(){
memset(vis, 0, sizeof(vis));
while(que.size()){
que.pop();
}
node p;
p.x = sx; p.y = sy;
p.time = 0;
que.push(p);
vis[sx][sy] = 1;
while(que.size()){
node f = que.top();
que.pop();
if(f.x == ex && f.y == ey){
return f.time;
}
for(int i = 0; i<4; i++){
int fx = f.x+dx[i], fy = f.y+dy[i];
if(fx>=1 && fx<=n && fy>=1 && fy<=m && !vis[fx][fy]){
if(ma[fx][fy] == 'X'){
p.x = fx; p.y = fy; p.time = f.time;
que.push(p);
}
else{
p.x = fx; p.y = fy; p.time = f.time+1;
que.push(p);
}
vis[fx][fy] = 1;
}
}
}
return -1;
}
int main(){
while(scanf("%d %d", &n, &m) == 2 && n+m){
for(int i = 1; i<=n; i++){
scanf("%s", ma[i]+1);
}
scanf("%d %d", &sx, &sy);
scanf("%d %d", &ex, &ey);
int res = bfs();
printf("%d\n", res);
}
return 0;
}
HDU-2824 The Euler function(欧拉函数)
题意:给定a,b,求从a到b所有欧拉函数之和
题解:直接欧拉函数打表即可。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
long long eul[3000010];
//欧拉函数打表
void Eul(){
eul[1] = 1;
for(long long i = 2; i<3000010; i++){
eul[i] = i;
}
for(long long i = 2; i<3000010; i++){
if(eul[i] == i){
for(long long j = i; j<3000010; j+=i){
eul[j] = eul[j]/i*(i-1);
}
}
}
}
int main(){
Eul();
long long a, b;
long long res = 0;
while(scanf("%lld %lld", &a, &b) == 2){
res = 0;
for(long long i = a; i<=b; i++){
res += eul[i];
}
printf("%lld\n", res);
}
return 0;
}