M:一开始想的bfs松弛dp,但是T了。
然后想的是去枚举全部的高度,然后bfs判断,显然这也会T。
但是可以发现的是,其实我们只需要找到最大的能承受的高度即可。
所以就可以二分了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5+5; const int M = 1e6+5; const LL Mod = 9999999967; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read() { LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; int a[1005][1005],b[4][2] = {1,0,-1,0,0,1,0,-1},n; int vis[1005][1005]; bool bfs(int dis) { memset(vis,0,sizeof(vis)); queue<pii> Q; Q.push(pii{1,1}); vis[1][1] = 1; if(a[1][1] < dis) return false; while(!Q.empty()) { int x = Q.front().first; int y = Q.front().second; Q.pop(); if(x == n && y == n) return true; for(int i = 0;i < 4;++i) { int px = x + b[i][0]; int py = y + b[i][1]; if(px >= 1 && px <= n && py >= 1 && py <= n && !vis[px][py] && a[px][py] >= dis) { vis[px][py] = 1; Q.push(pii{px,py}); } } } return false; } int main() { n = read(); for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) a[i][j] = read(); int L = 1,r = 100000,ans; while(L <= r) { int mid = (L + r) >> 1; if(bfs(mid)) { ans = mid; L = mid +1; } else r = mid - 1; } int q;q = read(); while(q--) { int x;x = read(); printf("%s ",x <= ans ? "Wuhu" : "Hmmm"); } system("pause"); return 0; }
F:大意了,这里模数很大,会爆longlong。所以上int128
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<double,int> pii; const int N = 1e8+5; const int M = 1e6+5; const LL Mod = 9999999967; #define rg register #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read() { LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; __int128_t quick_mi(__int128_t a,__int128_t b) { __int128_t re = 1; a %= Mod; while(b) { if(b&1) re = (re * a) % Mod; a = (a * a) % Mod; b >>= 1; } return re; } int main() { int ca;ca = read(); while(ca--) { LL x,i;x = read(),i = read(); LL ans = (LL)quick_mi((__int128_t)x,(__int128_t)i); printf("%lld ",ans); } system("pause"); return 0; }
J:dsu on tree,比赛的时候想到了,但是中间没处理好。
不过我的思路还是对的。
先算贡献,再去加入子树的点值。
但是这里由于对于u这个节点,首先算贡献的时候不能算入,然后加边的时候又要算入。
所以我们solve的时候直接对一个个子节点遍历去计算,主要u这个点的贡献一定要加上。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<double,int> pii; const int N = 1e5+5; const int M = 1e6+5; const LL Mod = 9999999967; #define rg register #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read() { LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; int n,val[N],ssize[N],son[N],Son = 0; LL ans = 0; vector<int> G[N]; unordered_map<int,int> mp; void dfs(int u,int fa) { ssize[u] = 1; for(auto v : G[u]) { if(v == fa) continue; dfs(v,u); ssize[u] += ssize[v]; if(ssize[v] > ssize[son[u]]) son[u] = v; } } void solve(int u,int fa,int top) { ans += mp[2 * val[top] - val[u]]; for(auto v : G[u]) { if(v == fa || v == Son) continue; solve(v,u,top); } } void add(int u,int fa,int num) { mp[val[u]] += num; for(auto v : G[u]) { if(v == fa || v == Son) continue; add(v,u,num); } } void dfs1(int u,int fa,int opt) { for(auto v : G[u]) { if(v == fa || v == son[u]) continue; dfs1(v,u,0); } if(son[u]) dfs1(son[u],u,1),Son = son[u]; for(auto v : G[u]) { if(v == fa || v == son[u]) continue; solve(v,u,u); add(v,u,1); } mp[val[u]]++; Son = 0; if(opt == 0) add(u,fa,-1); } int main() { n = read(); for(int i = 1;i <= n;++i) val[i] = read(); for(int i = 1;i < n;++i) { int x,y;x = read(),y = read(); G[x].push_back(y); G[y].push_back(x); } dfs(1,0); dfs1(1,0,0); printf("%lld ",ans * 2); system("pause"); return 0; }
A:首先,除法可以满足分子分母取模后依旧成立的性质。
那么我们处理出所有x值然后做一次逆元即可。
但是这题就是卡了内存,1e8的空间开不出来。
但是仔细看我们最多只需要处理2e5的数据,所以map来记录下即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5+5; const int M = 1e6+5; const LL Mod = 1e9+7; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline int read() { int x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; LL quick_mi(LL a,LL b) { LL re = 1; a %= Mod; while(b) { if(b&1) re = (re * a) % Mod; a = (a * a) % Mod; b >>= 1; } return re; } pii a[N]; int b[N << 1],tot = 0; map<int,int> mp; int main() { int n;n = read(); for(int i = 1;i <= n;++i) a[i].first = read(),a[i].second = read(),b[++tot] = a[i].first,b[++tot] = a[i].second; sort(b + 1,b + tot + 1); int L = 0; LL x = 1; mp[0] = 1; for(int i = 1;i <= tot;++i) { while(L < b[i]) x = x * (x + 1) % Mod,L++; mp[b[i]] = x; } for(int i = 1;i <= n;++i) { if(a[i].first < a[i].second) swap(a[i].first,a[i].second); LL ans = mp[a[i].first] * quick_mi(mp[a[i].second],Mod - 2) % Mod; printf("%lld ",ans); } system("pause"); return 0; }