zoukankan      html  css  js  c++  java
  • 题解-ARC113

    ARC113

    铭记这场暂时没有补的 F 题和场上没有做出的 E 题。

    说句闲话,不知道有没有人和我一样想:Codeforces 查黑这么严,都有许多人开黑,许多成功。那么这个 AtCoder 很多时候场上觉得不简单的题评成菜色是不是也有原因啊。


    ARC113A A*B*C

    [egin{aligned} ans =& sum_{i = 1} ^ K sum_{j = 1} ^ {lfloor K/i floor} d(j)\ =& sum_{i = 1} ^ K sum_{j = 1} ^ {lfloor K/i floor} lfloorfrac{K}{ij} floor end{aligned}]

    整除分块套整除分块即可,时间复杂度 (Theta(K))

    int n;
     
    i64 sum(int n) {
    	i64 res=0;
    	for (int l=1,r;l<=n;l=r+1) {
    		r=n/(n/l);
    		res+=1ll*(r-l+1)*(n/l);
    	}
    	return res;
    }
     
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    	cin>>n;
    	i64 res=0;
    	for (int l=1,r;l<=n;l=r+1) {
    		r=n/(n/l);
    		res+=sum(n/l)*(r-l+1);	
    	}
    	cout<<res<<'
    ';
    	return 0;
    }
    

    ARC113B A^B^C

    容易发现,任意一个 (k : 1le kle 9) 的循环节必然如下:

    [1, a, b, c, d, a, b, c, d, dots ]

    有可能 (d = 1),也可能 (b = d) 甚至 (a = b = c = d)

    由于 (B ^ C > 0),可以求出 (P = B ^ C mod 4 + 4),然后答案就是 (A ^ P mod 10)

    int a,b,c;
    
    int mypow(int a,int x,int mod) {
    	int res=1;
    	for (;x;x>>=1,a=a*a%mod)
    		if (x&1) res=res*a%mod;
    	return res;
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    	cin>>a>>b>>c,a%=10,b%=4;
    	cout<<mypow(a,4+mypow(b,c,4),10)<<'
    ';
    	return 0;
    }
    

    ARC113C String Invasion

    从右往左贪心,每次遇到两个相邻的字符,就把右边都涂成这个字符。

    然后可以得到右边与这个字符不相同的字符的个数个贡献。

    具体实现可以维护当前右边每个字符有多少个。

    const int xn=2e5,xc=26;
    int n,last[xc];
    string s;
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    	cin>>s,n=sz(s);
    	rep(c,xc) last[c]=0;
    	i64 res=0;
    	per(i,n) {
    		rep(c,xc) if (s[i]-'a'!=c)
    			++last[c];
    		if (i>=2 and s[i-1]==s[i-2]
    		and s[i-1]!=s[i]) {
    			res+=last[s[i-1]-'a'];
    			rep(c,xc) last[c]=n-i;
    			last[s[i-1]-'a']=0;
    		}
    	}
    	cout<<res<<'
    ';
    	return 0;
    }
    

    ARC113D Sky Reflector

    没法直接处理限制必然从分析性质入手。

    那么先设这个 Grid(C) 吧。

    对于每个 (i)(A[i] = min_{j = 1} ^ m C[i][j])

    所以 (forall j in [1,m] : C[i][j] ge A[i])

    同理,(C[i][j] le B[j]),所以 (forall i, j : B[j] ge A[i])

    如果 (n ge 2, m ge 2),这里必然可以挑选出每行一个格子染成红色,每列一个格子染成蓝色,使得没有格子被染成两种颜色。

    然后这样就只需要统计满足上述条件的序列数了,具体见代码。

    所以特殊处理 (n = 1)(m = 1) 的情况即可。

    这里可以图个方便,注意到 (n, m)(m, n) 是一样的,令 (n le m) 可以少特判一次。

    int n,m,k;
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    	cin>>n>>m>>k;
    	if (n>m) swap(n,m);
    	int res=0;
    	if (n==1) {
    		if (m==1) cout<<k<<'
    ';
    		else cout<<mypow(k,m)<<'
    ';
    		return 0;
    	}
    	rep(i,k) res=(res+(mint (mypow(i+1,n))
    	-mypow(i,n))*mypow(k-i,m)).x;
    	cout<<res<<'
    ';
    	return 0;
    }
    

    ARC113E Rvom and Rsrev

    这题其实没那么可怕吧,细节和重复工作有点多而已,好久没写代码,场上没调出来 /kk

    大致分析一下,最后有几种可能(易证其他的都是可以转化得更优的):

    a,全 b,一堆 b 中一个 a,一堆 b 然后一堆 a

    再分析一下删 a 转和删 b 转分别的目的是什么:

    a 很简单:把中间挡住后面的 ba 干掉 或 把中间的 a 甩到结尾去。

    这里需要区分:中间的 a 是狼,是野兽,会伤害它们后面的 b

    结尾的 a 是狗,是宠物,因为 a 的字典序比空位大。

    b 就是很无奈的选择了,最多一次。必然是恰有一个 a 卡在中间,然后为了把这个 a 甩到结尾牺牲两个 b

    然后这题萌新认为最大的难点,就是要发现,这样删 b 的作用可能不止把一个 a 甩到后面去,前面一些被删掉的中间的 a,也可以复活,然后搭便车,逃到结尾。

    具体实现见代码和注释。

    int n;
    string s;
    
    int mymain() {
    	cin >> s, n = sz(s);
    	int la = -1, lb = -1; // 最后的 a 和 b 的位置
    	int ca = 0, cb = 0; // a 和 b 初始的数量
    	rep(i, 0, n) {
    		if (s[i] == 'a') la = i, ++ca;
    		else lb = i, ++cb;
    	}
    	if (cb == 0 or ca == 0)
    		return cout << s << '
    ', 0; // 全 a 或全 b
    	if (lb == n - 1) { // b 结尾,a 没法靠删 a 甩到后面
    		if (ca & 1) { // 中间的 a 删不光,那么留下最后一个 a
    			int rcb = n - 1 - la; // 最后的 a 右边的 b 数
    			int lcb = cb - rcb;  // a 左边的 b 数
    			if (rcb <= 2 or !lcb) { // 决策删 b,前者删了不如不删,后者没法删,那么不删
    				rep(i, 0, lcb) cout << 'b';
    				cout << 'a';
    				rep(i, 0, rcb) cout << 'b';
    				cout << '
    ';
    			} else { // 决定删 b,统计搭便车
    				int ba = -1, baa = -1; // 找到一个 bab 或 baa 的位置,至少有一个
    				/* 
    				※:这里用到了有点重要的贪心性质,下面也会用到:
    				如果一段 a 只有 1 个,那么删一个后面的 a 和这里的 a 把 a 甩到后面去不优
    				否则是优的。所以这些单个的 a 可以自相残杀只留最后一个 
    				*/
    				rep(i, 0, n - 2) {
    					if (s[i] == 'a') continue;
    					if (s[i+1] == 'b') continue;
    					if (s[i+2] == 'a') baa = i;
    					else ba = i;
    				}
    				if (~baa) ba = baa; // 第一次用删 b 找甩点甩同样遵循 ※
    				int ab = ba + 1;
    				for (; s[ab] == 'a'; ++ab); // 找到这段 a 的长度
    				int ra = ab - ba - 1, oa = 0; // 得出当前后缀 a 的长度,是否剩余单个 a
    				for (int i = 0, j; i < ba; i = j) {
    					j = i + 1;
    					if (s[i] == 'b') continue;
    					for (; s[j] == 'a'; ++j);
    					if (j - i >= 2) ra += j - i - 2;
    					else oa ^= 1;
    				} // 统计删 b 甩点 ba 的左边
    				for (int i = ab, j; i < n; i = j) {
    					j = i + 1;
    					if (s[i] == 'b') continue;
    					for (; s[j] == 'a'; ++j);
    					if (j - i >= 2) ra += j - i - 2;
    					else oa ^= 1;
    				} // 统计删 b 甩点 ba 的右边
    				ra -= oa; // 此时 ra 必然 >= 1,这样就是浪费一个后缀 a 消掉中间 a
    				rep(i, 0, cb - 2) cout << 'b';
    				rep(i, 0, ra) cout << 'a';
    				cout << '
    ';
    			}
    		} else { // 中间的 a 删光了,不用牺牲 b 了
    			rep(i, 0, cb) cout << 'b';
    			cout << '
    ';
    		}
    	} else { // 本来就有后缀 a
    		int ra = n - 1 - lb, oa = 0; // 当前后缀 a 长度,有没有中间的单个 a
    		for (int i = 0, j; i < lb; i = j) {
    			j = i + 1;
    			if (s[i] == 'b') continue;
    			for (; s[j] == 'a'; ++j);
    			if (j - i >= 2) ra += j - i - 2;
    			else oa ^= 1; 
    		}
    		ra -= oa; // 同理,消掉中间的 a
    		rep(i, 0, cb) cout << 'b';
    		rep(i, 0, ra) cout << 'a';
    		cout << '
    ';		
    	}
    	return 0;
    }
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    	int cas; cin >> cas;
    	while (cas--) mymain();
    	return 0;
    }
    

    本人已在加速退役,大家敬请随便爆 D

  • 相关阅读:
    Mysql update case
    phpexcel导出excel等比例缩放图片
    phpexcel错误 You tried to set a sheet active by the out of bounds index: 1解决办法
    phpexcel操作
    Java io基础
    java线程基础
    java 集合基础(适用单线程)
    java 泛型深入
    Java反射基础
    Java泛型基础
  • 原文地址:https://www.cnblogs.com/George1123/p/14429417.html
Copyright © 2011-2022 走看看