51nod 模拟2
A. 直接pow,代码略
B
分子分母分开处理
转移到
然后所以
可以找规律完成递推
%:pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
const int L = 1E5+10, R = 500000002;
#define int ll
typedef long long ll;
const ll MOD = 1e9+7, PHI = MOD-1;
ll qpow(ll a, ll b,ll mod){
ll ret = 1;
for(;b;b>>=1){
if(b & 1) ret = ret * a %mod;
a = a * a % mod;
}
return ret;
}
ll inv(ll x){
return qpow(x, MOD-2, MOD);
}
ll get(ll a, ll b){
if(b == 0) return a;
ll x = (a + 1) * inv(2) % MOD, y = (a - 1) * inv(2) % MOD;
ll p = qpow(x, (qpow(2, b, PHI)), MOD) , q = qpow(y, qpow(2, b, PHI),MOD);
return (p + q)%MOD * inv(p - q)%MOD;
}
void solve(){
ll x, n;
cin >> x >> n;
--n;
cout << (get(x, n)+ MOD)%MOD << endl;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
}
C
非常有趣
我们的目的是把每个点的最小alpha求出来
如何求?一条边有两个方向,一条边和一个方向可以决定一个贡献
我们把有向边定向,然后求每条有向边的alpha
每条有向边可以对的子树产生贡献
对子树贡献可以用线段树区间取维护
线段树每个叶子表示为根时的最小alpha
#include<bits/stdc++.h>
using namespace std;
typedef long double ld;
const int N = 1e5 + 10, TR = 4 * N, E = 2 * N;
const ld eps = 1e-14;
int n,k, q;
struct segment_tree{
struct node{
ld laz;
}tree[TR];
void update(int rt, ld val){
tree[rt].laz = max(tree[rt].laz, val);
}
void modify(int rt,int l, int r, int s, int t, ld val){
if(s > t) return;
if(s <= l && r <= t){
tree[rt].laz = max(tree[rt].laz, val);
return;
}
int mid = (l + r) >> 1;
if(s <= mid) modify(rt<<1, l, mid, s ,t, val);
if(t > mid) modify(rt<<1|1, mid+ 1, r, s ,t, val);
}
ld query(int rt, int l, int r, int s){
ld ret = tree[rt].laz;
if(l >= r){
return ret;
}
int mid = (l + r) >> 1;
if(s <= mid)
return max(ret, query(rt<<1, l, mid, s));
else
return max(ret, query(rt<<1|1, mid + 1, r, s));
}
}segt;
struct graph{
struct edge{
int nxt, to;
}e[E];
graph(){
elen = 1;
}
int elen, head[N];
void inse(int frm, int to){
e[++elen] = {head[frm], to};
head[frm] = elen;
++deg[to];
}
void insf(int u, int v){
inse(u, v),inse(v, u);
}
int fat[N];
int siz[N], deg[N];
int son1[N], son2[N];
int dfn[N], tim;
ld val[E];
void dfs1(int u){
siz[u] = 1;
for(int i = head[u]; i; i = e[i].nxt){
int v = e[i].to;
if(v == fat[u]) continue;
fat[v] = u;
dfs1(v);
siz[u] += siz[v];
if(siz[v] > siz[son1[u]]){
son2[u] = son1[u], son1[u] = v;
}else if(siz[v] > siz[son2[u]]){
son2[u] = v;
}
}
}
void dfs2(int u){
for(int i = head[u]; i;i = e[i].nxt){
int v = e[i].to;
if(v == fat[u]) continue;
val[i] = deg[v] <= 2 ? 0 : ld(siz[son1[v]]) /siz[v];
dfs2(v);
}
for(int j = head[u]; j;j= e[j].nxt){
int i = (j ^ 1);
int v = e[j].to;
if(v == fat[u]) continue;
int mxp = (v == son1[u]) ? son2[u] : son1[u];
int mxs = max( n - siz[u], siz[mxp]);
val[i] = deg[u] <= 2 ? 0 :ld(mxs) / (n - siz[v]);
}
}
void dfs3(int u){
dfn[u] = ++tim;
for(int i = head[u]; i; i= e[i].nxt){
int v = e[i].to;
if(v == fat[u]) continue;
dfs3(v);
}
}
void dfs4(int u){
for(int i = head[u]; i;i = e[i].nxt){
int v = e[i].to;
if(v == fat[u]) continue;
int j = i ^ 1;
segt.modify(1, 1, n, dfn[v], dfn[v] + siz[v] - 1, val[j]);
dfs4(v);
}
for(int i = head[u]; i;i = e[i].nxt){
int v = e[i].to;
if(v == fat[u]) continue;
segt.modify(1, 1, n, 1, dfn[v] - 1, val[i]);
segt.modify(1, 1 ,n, dfn[v] + siz[v], n ,val[i]);
}
}
}G;
ld wei[N];
int main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> k;
for(int i = 1; i < n; ++i){
int u, v;
cin >> u >> v;
G.insf(u, v);
}
G.dfs1(1);
G.dfs2(1);
G.dfs3(1);
G.dfs4(1);
for(int i = 1; i <= n; ++i){
wei[i] = segt.query(1, 1, n, G.dfn[i]);
}
for(int i = 1; i <= n; ++i){
if(G.deg[i] >= 2){
int msiz = max(G.siz[G.son1[i]], n - G.siz[i]);
wei[i] = max(wei[i], (ld)1.0 * msiz / n);
}
}
sort(wei + 1, wei + 1 + n);
cin >> q;
int las = 0;
for(int i = 1; i <= q ; ++i){
int u , v;
cin >> u >> v;
u = u xor (las * k), v = v xor(las * k);
ld key = ld(u)/v;
las = (upper_bound(wei + 1, wei + 1 + n, key + eps) - wei - 1);
cout << las << endl;
}
return 0;
}
D
发现价钱和天数是等价的,于是我们设工厂的两个关建值为
商店为
越小越好,越大越好
我们分别排序,并且去掉一定不可能产生贡献的点(若均比另一个点大)
接下来发现有决策单调性,分治即可
证明:设为商店,为两个工厂,若比优,则
展开后移项,得
因为,所以 ,
又因为对, 所以i$优
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+10;
struct t_a{
int a, b;
bool operator < (const t_a &rhs) const{
return tie(a, b) < tie(rhs.a, rhs.b);
}
}x[N],t1[N];
struct t_b{
int c, d;
bool operator <(const t_b & rhs)const{
return tie(d, c) > tie(rhs.d, rhs.c);
}
}y[N],t2[N];
ll ans = 0;
ll calc(t_a a, t_b b){
if(b.c - a.a < 0 || b.d - a.b < 0) return 0;
return 1ll * (b.c - a.a) * (b.d- a.b);
}
void solve(int l, int r, int s, int t){
if(l > r || s > t) return;
int mid = (l + r) >> 1;
int pos = s;
for(int i = s + 1; i <= t; ++i){
if(calc(t1[i], t2[mid]) >= calc(t1[pos], t2[mid])){
pos = i;
}
}
ans = max(ans, calc(t1[pos], t2[mid]));
solve(l, mid - 1, s, pos);
solve(mid + 1, r, pos, t);
}
int m, n;
int main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> m >> n;
for(int i = 1; i <= m; ++i){
cin >> x[i].a >> x[i].b;
}
for(int i = 1; i <= n; ++i){
cin >> y[i].c >> y[i].d;
}
sort(x + 1, x + m + 1);
sort(y + 1 ,y + n + 1);
int c1 = 0, c2 = 0;
t1[++c1] = x[1];
t2[++c2] = y[1];
for(int i = 2; i <= m; ++i){
if(t1[c1].b <= x[i].b) continue;
t1[++c1] = x[i];
}
for(int i = 2; i <= n; ++i){
if(t2[c2].c >= y[i].c) continue;
t2[++c2] = y[i];
}
m = c1, n = c2;
for(int i = 1; i <= n; ++i){
int pos = lower_bound(t1 + 1, t1 + 1 + m, t_a{t2[i].c, -1}) - t1 - 1;
if(pos == 0 || t1[pos].b >= t2[i].d){
t2[i].c = t2[i].d = -1;
}
}
c2 = 0;
for(int i = 1; i <= n; ++i){
if(t2[i].c == -1) continue;
y[++c2] = t2[i];
}
n = c2;
memcpy(t2, y, sizeof(t2));
solve(1, n, 1, m);
cout << ans << endl;
return 0;
}
作者:cdsidi
出处:https://www.cnblogs.com/cdsidi/p/16583937.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】