B. super_log
https://nanti.jisuanke.com/t/41299
很容易推出来是一个连续的幂次。这里主要是要知道扩展欧拉定理对互质肯定也是生效的,不需要整这么多东西。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int qpow2(ll x, int n, int m) {
int _2m = m + m;
ll res = 1;
while(n) {
if(n & 1) {
res = res * x;
if(res >= _2m)
res = (res % m) + m;
}
x = x * x;
if(x >= _2m)
x = (x % m) + m;
n >>= 1;
}
return res;
}
bool np[1000005];
int phi[1000005];
int pri[800005];
int ptop;
void sieve(int n) {
np[1] = 1;
phi[1] = 1;
for(int i = 2; i <= n; ++i) {
if(!np[i]) {
pri[++ptop] = i;
phi[i] = i - 1;
}
for(int j = 1; j <= ptop; ++j) {
int t = i * pri[j];
if(t > n)
break;
np[t] = 1;
if(!(i % pri[j])) {
phi[t] = phi[i] * pri[j];
break;
} else
phi[t] = phi[i] * (pri[j] - 1);
}
}
}
int solve(int a, int b, int m) {
if(m == 1 || b == 0)
return 1;
else
return qpow2(a, solve(a, b - 1, phi[m]), m);
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
sieve(1000000);
int T;
scanf("%d", &T);
while(T--) {
int a, b, m;
scanf("%d%d%d", &a, &b, &m);
printf("%d
", solve(a, b, m) % m);
}
}
D. Robots
https://nanti.jisuanke.com/t/41301
这个题目的DAG我已经不知道吐槽什么好了。说一下花费的期望是怎么来的,事实上和天数的期望是一个道理。
据说可以把每一天的花费反过来,但为什么这样是等价的?
注意下面这个是倒推,就是用 (day[i]) 表示从 (i) 号点开始到达 (n) 号点的期望天数。
设 (u) 点可以到达 (v_1,v_2,v_3) ,那么天数的期望明显有 (day[u]=frac{1}{3+1}(day[v_1]+day[v_2]+day[v_3]+day[u])+1)
用 (cost[i]) 表示从 (i) 号点开始到达 (n) 号点的期望花费,那么花费的期望明显有 (cost[u]=frac{1}{3+1}(cost[v_1]+cost[v_2]+cost[v_3]+cost[u])+day[u])
由定义明显有 (day[n]=0) 和 (cost[n]=0)
qls的办法更好:
求花费的期望,假设由上面的方法得到了期望的天数。
那么答案为:
(EX[cost[1]]=sumlimits_{i=0}frac{i*(i+1)}{2}p_i=frac{1}{2}(sumlimits_{i=0}i^2p_i+sumlimits_{i=0}ip_i))
那么需要求的是前一项。
由 (EX[(X+1)^2]=EX[X^2]+2EX[X]+1)
得到后面的转移。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 5;
int n, m;
vector<int> G[MAXN], AG[MAXN];
int outdeg[MAXN];
double day[MAXN], day2[MAXN];
queue<int> Q;
void topo() {
day[n] = 0.0;
day2[n] = 0.0;
for(auto p : AG[n]) {
--outdeg[p];
if(!outdeg[p]) {
Q.push(p);
}
}
while(!Q.empty()) {
int u = Q.front();
Q.pop();
int od = (int)G[u].size();
day[u] = 1.0;
for(auto v : G[u])
day[u] += day[v] + 1.0;
day[u] /= od;
day2[u] = (2.0 * day[u] + 1.0);
for(auto v : G[u])
day2[u] += day2[v] + 2.0 * day[v] + 1.0;
day2[u] /= od;
for(auto p : AG[u]) {
--outdeg[p];
if(!outdeg[p]) {
Q.push(p);
}
}
}
return;
}
int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
#endif // Yinku
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
G[i].clear();
AG[i].clear();
outdeg[i] = 0;
}
for(int i = 1; i <= m; ++i) {
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
AG[v].push_back(u);
++outdeg[u];
}
topo();
printf("%.2f
", 0.5 * (day2[1] + day[1]));
}
}