• 51nod 模拟2


    A. 直接pow,代码略
    B
    分子分母分开处理
    \(a/b\)转移到\(\frac{\frac{a}{b}+\frac{b}{a}}{2} = \frac{a^2+b^2}{2ab}\)
    然后\(a'=a^2+b^2, b'=2ab\)所以\(a'+b'=(a+b)^2, a'-b' = (a-b)^2\)
    可以找规律完成递推

    %: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
    每条有向边\((u,v)\)可以对\(u\)的子树产生贡献
    对子树贡献可以用线段树区间取\(max\)维护
    线段树每个叶子\(u\)表示\(u\)为根时的最小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
    发现价钱和天数是等价的,于是我们设工厂的两个关建值为\(a, b\)
    商店为\(c,d\)
    \(a,b\)越小越好,\(c,d\)越大越好
    我们分别排序,并且去掉一定不可能产生贡献的点(若\(a, b\)均比另一个点大)
    接下来发现有决策单调性,分治即可
    证明:设\(u\)为商店,\(i,j\)为两个工厂\(i<j\),若\(j\)\(i\)优,则
    \((c_u - a_i) * (d_u - b_i) < (c_u - a_j) * (d_u - b_j)\)
    展开后移项,得
    \(d_u(a_j-a_i) + a_jb_j< c_u(b_i-b_j) + a_kb_k\)
    因为\(i<j\),所以\(a_i-a_i > 0\) ,\(b_i - b_j>0\)
    又因为对\(v > u\), \(d_v < d_u, c_v < c_u\)所以\(j仍然比\)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;
    }
    
  • 相关阅读:
    CLR via C#深解笔记三
    CLR via C#深解笔记二
    CLR via C#深解笔记一
    C#参考:Linq 概述
    JavaScript
    jQuery
    JavaScript
    云原生
    python模块----optparse模块、argparse模块 (命令行解析模块)
    python模块----pymysql模块 (连接MySQL数据库)
  • 原文地址:https://www.cnblogs.com/cdsidi/p/16583937.html
Copyright © 2020-2023  润新知