zoukankan      html  css  js  c++  java
  • 题解:AtCoder Beginner Contest 189

    C - Mandarin Orange

    提供一种不一样的 (mathcal{O}(n log n)) 的方法。

    设对于第 (i) 个位置,左边第一个大于它的位置记为 (L_i) ,右边第一个大于它的位置记为 (R_i)

    发现对于第 (i) 个位置的值作为 (x) 时的最优解即为 ((R_i-L_i-1) imes val_i)

    可以使用双向链表处理,具体操作见代码。

    int n, arr[N], id[N], Nxt[N], Pre[N];
    inline bool cmp(int A, int B) {return arr[A] == arr[B] ? A < B : arr[A] > arr[B];}
    int main() {
    	scanf("%d", &n);
    	forn(i,1,n) scanf("%d", arr+i), Pre[i] = i-1, Nxt[i] = i+1, id[i] = i;
    	int Ans = 0;
    	sort(id+1, id+n+1, cmp);
    	forn(i,1,n) {
    		int l = Pre[id[i]], r = Nxt[id[i]];
    		Nxt[l] = r,Pre[r] = l;
    		Ans = Max(Ans, (r-l-1) * arr[id[i]]);
    	}
    	printf("%d
    ", Ans);
    	return 0;
    }
    

    D - Logical Expression

    简单递推题。

    (T_i)(F_i) 分别表示前 (i) 个运算符计算结果的为 ( ext{True})( ext{False}) 的数量。

    如果第 (i) 个计算符为 AND ,则有

    [T_i = T_{i-1} ]

    [F_i = F_{i-1} imes 2 + T_{i-1} ]

    否则

    [F_i = F_{i-1} ]

    [T_i = T_{i-1} imes 2 + F_{i-1} ]

    答案即为 (T_n)

    E - Rotate and Flip

    这道题可以不用矩阵,也并不麻烦。

    观察每个操作:

    opt1 ((x,y) ightarrow (y,-x))

    opt2 ((x,y) ightarrow (-y,x))

    opt3 ((x,y) ightarrow (2 imes p-x,y))

    opt4 ((x,y) ightarrow (x,2 imes p-y))

    可以发现对于任何几种操作相加,对于原来的横纵坐标,都能表示成

    ((sum_x ext{opt}_x x, sum_y ext{opt}_y y))(( sum_y ext{opt}_y y,sum_x ext{opt}_x x))

    (sum) 表示一个值, ( ext{opt}) 表示正负号, (x/y) 表示原来横坐标或纵坐标的值

    在具体操作时,只需要离线处理,维护 (sum_{x/y}) , ( ext{opt}_{x/y}) , 是否翻转横纵坐标, 5 个变量即可。

    inline bool cmp(int NA, int NB) {return A[NA] < A[NB];}
    int main() {
    	scanf("%d", &n);
    	forn(i,1,n) scanf("%d%d", X+i, Y+i);
    	scanf("%d", &m);
    	forn(i,1,m) {
    		scanf("%d", opt+i);
    		if(opt[i] > 2) scanf("%d", p+i);
    	}
    	scanf("%d", &q);
    	forn(i,1,q) scanf("%d%d", A+i, B+i), id[i] = i;
    	sort(id+1, id+q+1, cmp);
    	LL trn = 0, Xopt = 1, Yopt = 1, Xsum = 0, Ysum = 0;
    	int j = 1;
    	forn(i,1,m+1) {
    		while(A[id[j]] == i-1) {
    			Xans[id[j]] = Xsum + Xopt*1ll*X[B[id[j]]];
    			Yans[id[j]] = Ysum + Yopt*1ll*Y[B[id[j]]];
    			if(trn) swap(Xans[id[j]], Yans[id[j]]);
    			++j;
    		}
    		if(opt[i] == 1) {
    			if(trn) {
    				Yopt = -Yopt;
    				Ysum = -Ysum;
    			} else {
    				Xopt = -Xopt;
    				Xsum = -Xsum;	
    			}
    			trn^=1;
    		} else if(opt[i] == 2) {
    			if(trn) {
    				Xopt = -Xopt;
    				Xsum = -Xsum;	
    			} else {
    				Yopt = -Yopt;
    				Ysum = -Ysum;
    			}
    			trn^=1;
    		} else if(opt[i] == 3) {
    			if(trn) {
    				Ysum = 2ll*p[i] - Ysum;
    				Yopt = -Yopt;
    			} else {
    				Xsum = 2ll*p[i] - Xsum;
    				Xopt = -Xopt;	
    			}
    		} else {
    			if(trn) {
    				Xsum = 2ll*p[i] - Xsum;
    				Xopt = -Xopt;
    			} else {
    				Ysum = 2ll*p[i] - Ysum;
    				Yopt = -Yopt;
    			}
    		}
    	}
    	forn(i,1,q) printf("%lld %lld
    ", Xans[i], Yans[i]);
    	return 0;
    }
    

    F - Sugoroku2

    (f_i) 表示从第 (i) 个格子到终点的次数期望,显然有:

    ( egin{cases} f_i = displaystyle{0} & igeq n\ f_i = displaystyle{f_0} & iin A \ f_i = displaystyle{frac{1}{m}sum_{j=i+1}^{i+m} f_j}+1 & ext{otherwise}\ end{cases} )

    这个式子不能直接求,但是每一个 (f_i) 可以表示成关于 (f_0) 的一次函数形式,最终为获得一个形如 (f_0 = k imes f_0+b) 的式子,直接解方程即可。

    所以可以用后缀和优化的 DP 来求出每一个一次函数,总复杂度仅为 (mathcal{O}(n))

    另附本题加强版

    #include<bits/stdc++.h>
    #define forn(i,s,t) for(register int i=(s);i<=(t);++i)
    #define form(i,s,t) for(register int i=(s);i>=(t);--i)
    using namespace std;
    const int N = 2e5+3;
    int n, m, k, a[N]; bool bck[N];
    long double f1[N], f2[N], suf1[N], suf2[N];
    int main() {
    	scanf("%d%d%d", &n, &m, &k);
    	long double C = (long double)1.0/m;
    	forn(i,1,k) scanf("%d", a+i), bck[a[i]] = 1;
    	form(i,n-1,0) {
    		if(bck[i]) {
    			suf1[i] = suf1[i+1];
    			suf2[i] = suf2[i+1] + 1.0;
    			continue ;
    		}
    		f1[i] = C*(suf1[i+1] - suf1[i+m+1]) + 1;
    		f2[i] = C*(suf2[i+1] - suf2[i+m+1]);
    		suf1[i] = suf1[i+1] + f1[i];
    		suf2[i] = suf2[i+1] + f2[i];
    	}
    	if(1-f2[0] < 1e-6) puts("-1");
    	else printf("%.4Lf
    ", f1[0]/(1-f2[0]));
    	return 0;
    }
    
  • 相关阅读:
    Dobbo
    Redis
    Sql语句模糊查询字符串的两种写法
    Python——labelImg安装
    Python——numpy中的 sum 函数
    Python——pymysql 操作数据库
    Axure RP9 授权码和密钥
    更改 pip install 默认安装依赖的路径(转载)
    pip 升级或者安装拓展包时遇见的问题
    在Windows命令行中编译运行C/C++程序(转载)
  • 原文地址:https://www.cnblogs.com/Ax-Dea/p/14320381.html
Copyright © 2011-2022 走看看