• 1104上午考试总结


    1104上午考试

    T1

    ​ 题目大意:

    ​ 如果一个数字的十进制表示中,有大于等于 1个 1,或者有大于等于 2 个 2,或者有大于等于 3 个 3,或者有大于等于 4个 4,或者有大于等于 5 个 5,或者有大于等于 6 个 6,或者有大于等于 7个 7,或者有大于等于 8 个 8,或者有大于等于 9 个 9,这个数字是 good number。
    ​ 问 L 到 R 之间 (包含 L 和 R) 有多少个 good number? ((L, R <= 1e9))

    ​ 记忆化搜索.(数位DP也可, 但我不会)

    ​ 单步容斥一下,可以求出不是good number的数字.

    ​ 我们从高位向低位填数, (f[now][s1][s2][s3][s4][s5][s6][s7][s8][s9])表示改填第(now)位时,数字(i)已经填了(si)个时的不是good number的数的个数.然后搜他就完了.注意那个(lim)表示限制,如果说(now + 1)位上填的数是(a[now + 1]),那么(now)位最高就只能填到(a[now]),不可填到9.

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int L, R, cnt, ans, a[11], t[11], f[11][1][2][3][4][5][6][7][8][9];
    
    int dfs(int now, int lim, int s1, int s2, int s3, int s4, int s5, int s6, int s7, int s8, int s9) {
    	if(s1 >= 1 || s2 >= 2 || s3 >= 3 || s4 >= 4 || s5 >= 5 || s6 >= 6 || s7 >= 7 || s8 >= 8 || s9 >= 9) return 0;
    	if(!now) return 1;
    	if(!lim && f[now][s1][s2][s3][s4][s5][s6][s7][s8][s9] != -1) return f[now][s1][s2][s3][s4][s5][s6][s7][s8][s9];
    	int up = lim ? a[now] : 9, res = 0;
    	for(int i = 0;i <= up; i++) {
    		if(i == 0) res += dfs(now - 1, lim && i == up, s1, s2, s3, s4, s5, s6, s7, s8, s9);
    		if(i == 1) res += dfs(now - 1, lim && i == up, s1 + 1, s2, s3, s4, s5, s6, s7, s8, s9);
    		if(i == 2) res += dfs(now - 1, lim && i == up, s1, s2 + 1, s3, s4, s5, s6, s7, s8, s9);
    		if(i == 3) res += dfs(now - 1, lim && i == up, s1, s2, s3 + 1, s4, s5, s6, s7, s8, s9);
    		if(i == 4) res += dfs(now - 1, lim && i == up, s1, s2, s3, s4 + 1, s5, s6, s7, s8, s9);
    		if(i == 5) res += dfs(now - 1, lim && i == up, s1, s2, s3, s4, s5 + 1, s6, s7, s8, s9);
    		if(i == 6) res += dfs(now - 1, lim && i == up, s1, s2, s3, s4, s5, s6 + 1, s7, s8, s9);
    		if(i == 7) res += dfs(now - 1, lim && i == up, s1, s2, s3, s4, s5, s6, s7 + 1, s8, s9);
    		if(i == 8) res += dfs(now - 1, lim && i == up, s1, s2, s3, s4, s5, s6, s7, s8 + 1, s9);
    		if(i == 9) res += dfs(now - 1, lim && i == up, s1, s2, s3, s4, s5, s6, s7, s8, s9 + 1);
    	}
    	return f[now][s1][s2][s3][s4][s5][s6][s7][s8][s9] = res;
    }
    
    int calc(int x) {
    	cnt = 0;
    	while(x) a[++ cnt] = x % 10, x /= 10;
    	return dfs(cnt, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    }
    
    int main() {
    	
    	cin >> L >> R; memset(f, -1, sizeof(f));
    	printf("%d", R - L + 1 - calc(R) - calc(L - 1));
    	
    	return 0;
    }
    

    T2

    ​ 题目大意:

    ​ 小M总共有N个花园,它们构成了一棵1号节点为根的有根树,所有边权均为1。定义一个点x的val[x]=min{y|y属于x的子树}。从第一时刻到第N时刻,每一时刻小M会从1号节点出发,按照一定的规则拜访一个花园(这个花园是确定的):

    ​ 1.如果小M在i号节点,它是叶子节点或者所有儿子都被拜访过则停在该节点。

    ​ 2.如果第i号节点存在儿子没有拜访过,则找到所有未拜访的儿子中val最小的儿子继续行走。

    ​ 3.小M会拜访最终停在的花园,且每次拜访后会返回一号节点。因为路程的原因小M的心情点数会减去1号节点到拜访节点的距离。

    ​ 因为走路会很累,所以小M可以在任意时刻停止拜访花园在花园中共有M阵和风吹过,每阵风会遍历x[i],y[i]这条链上的所有花园,且有z[i]的声音舒适度。最终小M的心情点数会加上max(size[i]-1,0)*z[i],size[i]表示小M最终拜访过的花园在这条链上的个数。请问在什么时候停止拜访,小M的心情值最高呢。

    ​ 首先遍历顺序是一定的.对于每个节点(x),它的贡献是(-dep[x] + sum z).

    ​ 但是题目说了"心情点数会加上(max(size[i]-1,0)*z[i])",这个减一就有点难搞,我们可以找到遍历顺序里第一个经过这条链的点,然后这个点的贡献不加当前的(z).对于给点加(z),直接树上点的差分就好了,记得在求lca的时候找出那个遍历顺序里第一个经过这条链的点是(x)还是(y).然后按遍历顺序统计答案就好了.

    #include <bits/stdc++.h>
    
    #define int long long
    
    using namespace std;
    
    inline long long read() {
    	long long s = 0, f = 1; char ch;
    	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
    	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
    	return s * f;
    }
    
    const int N = 1e5 + 5, inf = 1e9;
    vector <int> v[N];
    int n, m, cnt, ans, now, P, a, b;
    int w[N], f[N][21], dfn[N], val[N], dep[N], head[N];
    struct edge { int nxt, to; } e[N << 1];
    
    void add(int x, int y) {
    	e[++ cnt].nxt = head[x]; head[x] = cnt; e[cnt].to = y;
    }
    
    void get_val(int x, int fa) {
    	val[x] = x; dep[x] = dep[fa] + 1; f[x][0] = fa;
    	for(int i = head[x]; i ; i = e[i].nxt) {
    		int y = e[i].to; if(y == fa) continue;
    		get_val(y, x); val[x] = min(val[x], val[y]);
    	}
    }
    
    void make_f() {
    	for(int i = 1;i <= 20; i++)
    		for(int j = 1;j <= n; j++) f[j][i] = f[f[j][i - 1]][i - 1];
    }
    
    int LCA(int x, int y) {
    	int tag = 0;
    	if(dep[x] < dep[y]) tag = 1, swap(x, y);
    	for(int i = 20;i >= 0; i--) if(dep[x] - dep[y] >= (1 << i)) x = f[x][i];
    	if(x == y) return x;
    	for(int i = 20;i >= 0; i--) if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
    	a = val[x]; b = val[y]; if(tag) swap(a, b);
    	return f[x][0];
    }
    
    void make_w(int x, int fa) {
    	for(int i = head[x]; i ; i = e[i].nxt) {
    		int y = e[i].to; if(y == fa) continue;
    		make_w(y, x); w[x] += w[y];
    	}
    }
    
    void get_dfn(int x, int fa) {
    	priority_queue <pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
    	for(int i = head[x]; i ; i = e[i].nxt) {
    		int y = e[i].to; if(y == fa) continue;
    		q.push(make_pair(val[y], y));
    	}
    	while(!q.empty()) {
    		int y = q.top().second; q.pop();
    		get_dfn(y, x); 
    	}
    	dfn[++ cnt] = x;
    }
    
    signed main() {
    	
    	n = read(); m = read(); ans = -inf;	
    	for(int i = 1, x, y;i < n; i++)
    		x = read(), y = read(), add(x, y), add(y, x);
    	get_val(1, 0); make_f(); cnt = 0;
    	for(int i = 1, x, y, z;i <= m; i++) {
    		x = read(); y = read(); z = read();
    		int lca = LCA(x, y);
    		if(x == lca) { w[f[y][0]] += z; w[f[x][0]] -= z; }
    		else if(y == lca) { w[f[x][0]] += z; w[f[y][0]] -= z; }
    		else {
    			if(a < b) { w[f[x][0]] += z; w[y] += z; w[lca] -= z; w[f[lca][0]] -= z; }
    			else { w[f[y][0]] += z; w[x] += z; w[lca] -= z; w[f[lca][0]] -= z; }
    		}
    	}
    	get_dfn(1, 0); make_w(1, 0);
    	for(int i = 1;i <= n; i++) w[i] -= dep[i] - 1;
    	for(int i = 1;i <= cnt; i++) now += w[dfn[i]], ans = max(ans, now);
    	printf("%lld", ans);
    
    	return 0;
    }
    
  • 相关阅读:
    Beta冲刺第三天
    Beta冲刺第二天
    C#编程(三十三)----------Array类
    ComputeColStats UDF中 近似算法的介绍(续)
    云计算技术第三堂课20210317
    云计算与信息安全第三堂课20210316
    操作系统第三堂课20210315
    ROSPlan教程
    机器学习第二堂课20210311
    云计算技术第二堂课20210310
  • 原文地址:https://www.cnblogs.com/czhui666/p/13927040.html
Copyright © 2020-2023  润新知