2022年多校冲刺NOIP联训测试12 && 51nod 2023省选联训 第二场
发现我只是换了个网站做题,还变成赛制。。。。。
A 开根
直接用
考场脑抽,打了个二分
code
#include<cstdio>
#include<cmath>
using namespace std;
double n, m;
int main(){
scanf("%lf%lf",&n,&m);
printf("%.3lf\n",pow(n, 1 / m));
return 0;
}
B 迭代
发现
那么
计算即可
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll qpow(ll x, ll y, ll mod){
ll ans = 1;
for(; y; y >>= 1, x = x * x % mod)if(y & 1)ans = ans * x % mod;
return ans;
}
ll x, n;
const ll mod = 1000000007;
const ll inv2 = 500000004;
ll work(){
ll p2 = qpow(2, n - 1, mod - 1);
ll sum = qpow(x + 1, p2, mod);
ll det = qpow(x - 1, p2, mod);
ll a = (sum + det) * inv2 % mod;
ll b = (sum - det + mod) % mod * inv2 % mod;
ll ans = a * qpow(b, mod - 2, mod) % mod;
return ans;
}
int main(){
int t; scanf("%d",&t);
for(int i = 1; i <= t; ++i){
scanf("%lld%lld",&x,&n);
printf("%lld\n",work());
}
return 0;
}
C 平衡树
换根,考场一直在乱搞结果没有时间打这个题
还有考试时候真的降智啊,什么东西能够快速维护一堆数据的最大值并且支持快速单点修改?线段树啊啊啊啊!!!!
最近对有点魔怔了。。。。
维护,以及该点的,根节点的就是全局最大值,然后换根找最大值次大值,对该点单点修改即可
记得在线啊
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
inline int read(){
int x = 0;char c = getchar();
while(c < '0' || c > '9')c = getchar();
do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
return x;
}
const int maxn = 150005;
struct edge{int to,net;}e[maxn << 1 | 1];
int head[maxn],tot;
void add(int u, int v){
e[++tot].net = head[u];
head[u] = tot;
e[tot].to = v;
}
struct tree{
long double t[maxn << 2 | 1];
void modify(int x, int l, int r, int pos, long double val){
if(l == r){t[x] = val;return;}
int mid = (l + r) >> 1;
if(pos <= mid)modify(x << 1, l, mid, pos, val);
else modify(x << 1 | 1, mid + 1, r, pos, val);
t[x] = max(t[x << 1], t[x << 1 | 1]);
}
long double query(){return t[1];}
}t;
int size[maxn], si, n, k;
long double ap[maxn];
void dfs1(int x,int fa){
size[x] = 1;
int mx = 0;
for(int i = head[x]; i; i = e[i].net){
int v = e[i].to;
if(v == fa)continue;
dfs1(v, x);
size[x] += size[v];
mx = max(mx, size[v]);
}
t.modify(1, 1, n, x, mx == size[x] - 1 ? 0 : (long double)mx / size[x]);
}
int mx[maxn], cmx[maxn], son[maxn];
void dfs2(int x, int fa){
int cnt = 0;
for(int i = head[x]; i; i = e[i].net){
int v = e[i].to; ++cnt;
if(size[v] > mx[x]){
cmx[x] = max(mx[x], cmx[x]);
mx[x] = size[v]; son[x] = v;
}else cmx[x] = max(cmx[x], size[v]);
}
t.modify(1, 1, n, x, cnt > 1 ? (long double)mx[x] / si : 0);
ap[x] = t.query(); --cnt;
for(int i = head[x]; i; i = e[i].net){
int v = e[i].to;
if(v == fa)continue;
size[x] = si - size[v];
t.modify(1, 1, n, x, cnt > 1 ? (son[x] == v ? (long double) cmx[x] / size[x] : (long double) mx[x] / size[x]) : 0);
dfs2(v, x);
}
size[x] = si - size[fa];
t.modify(1, 1, n, x, cnt > 1 ? (son[x] == fa ? (long double) cmx[x] / size[x] : (long double) mx[x] / size[x]) : 0);
}
int main(){
n = read(), k = read();
for(int i = 1; i < n; ++i){
int u, v; u = read(); v = read();
add(u, v); add(v, u);
}
dfs1(1, 0); si = size[1];
dfs2(1, 0); sort(ap + 1, ap + n + 1);
int m = read(), las = 0;
for(int i = 1; i <= m; ++i){
int a = read() xor (las * k), b = read() xor (las * k);
printf("%ld\n",las = upper_bound(ap + 1, ap + n + 1, (long double)a / b) - ap - 1);
}
return 0;
}
D 致富之路
关于shuffle他活了
首先设分别表示天和价格
对于工厂那么要没有用
对于商店那么要没有用
用栈去除无用信息
如果一个商店在他结束之前没有工厂的小于他,那么该商店没有贡献,扔掉
这样剩下的商店一定存在决策点
然后我们证明存在决策单调性
若工厂劣于工厂()
那么
因为我们按照天数排序并维护单调递减的价格
发现 和 小于
单调递增,左边越来越小,单调递减右边越来越大,所以当前不优,以后一定不优
分治每次给商店找决策点,两边递归即可
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<random>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
inline int read(){
int x = 0;char c = getchar();
while(c < '0' || c > '9')c = getchar();
do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
return x;
}
const int maxn = 500055;
int n, m;
struct node{
int val,day;
bool operator < (const node &x)const{
return x.day > day;
}
}a[maxn],b[maxn],ls[maxn];
int sta[maxn], stb[maxn], ta, tb;
ll ans = 0;
void solve(int l1, int r1, int l2, int r2){
if(l1 > r1 || l2 > r2)return;
int mid = (l2 + r2) >> 1;
int pos = 0;
ll mx = -0x3f3f3f3f;
for(int i = l1; i <= r1; ++i){
ll nans = (0ll + b[mid].day - a[i].day) * (0ll + b[mid].val - a[i].val);
if(nans > mx){mx = nans, pos = i;}
}
ans = max(ans, mx);
solve(l1, pos, l2, mid - 1);
solve(pos, r1, mid + 1, r2);
}
int main(){
m = read(), n = read();
for(register int i = 1; i <= m; ++i)a[i].val = read(), a[i].day = read();
for(register int i = 1; i <= n; ++i)b[i].val = read(), b[i].day = read();
sort(a + 1, a + m + 1); sort(b + 1, b + n + 1);
for(register int i = m; i >= 1; --i){
while(ta && a[sta[ta]].val >= a[i].val)--ta;
sta[++ta] = i;
}
for(int i = 1; i <= ta; ++i)ls[i] = a[sta[ta - i + 1]];
for(int i = 1; i <= ta; ++i)a[i] = ls[i];
for(register int i = 1; i <= n; ++i){
while(tb && b[stb[tb]].val <= b[i].val)--tb;
stb[++tb] = i;
}
for(int i = 1; i <= tb; ++i)ls[i] = b[stb[i]];
for(int i = 1; i <= tb; ++i)b[i] = ls[i];
int mi = 0x3f3f3f3f, pa = 1, pb = 0;
for(int i = 1; i <= tb; ++i){
while(pa <= ta && a[pa].day < b[i].day)mi = min(mi, a[pa++].val);
if(mi < b[i].val)ls[++pb] = b[i];
}
tb = pb;
for(int i = 1; i <= tb; ++i)b[i] = ls[i];
solve(1, ta, 1, tb);
printf("%lld\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】