首页 > 其他分享 >Educational Codeforces Round 95 (Rated for Div. 2) G. Three Occurrences

Educational Codeforces Round 95 (Rated for Div. 2) G. Three Occurrences

时间:2024-10-03 17:23:05浏览次数:1  
标签:pre Educational Rated int valB valA Codeforces cnt sum

首先我们随机两个数组\(valA_x,valB_x\)。

对于数组\(a\),记\(cnt\)表示\(a_i\) 在前缀中出现的次数。

  1. 若\(cnt\equiv 0 \mod 3\),则\(b_i=valA_x\)
  2. 若\(cnt\equiv 1 \mod 3\),则\(b_i=valB_x\)
  3. 若\(cnt\equiv 2 \mod 3\),则\(b_i=valA_x \oplus valB_x\)

记\(pre_i\)表示\(b\)的前缀异或和,如果区间\([l.r]\)内每个数的出现次数都是\(3\)的倍数,则满足\(pre_r \oplus pre_{l-1} = 0\)

再用双指针求出\([l,r]\)表示对\(r\)来说的最大区间满足区间内任何一个数出现的次数都不超过3次。此时只要求出满足\(l\le pos\le r \and pre_r \oplus pre_{pos-1}\)的\(pos\)的个数,即可求出\(r\)对答案产生的贡献。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;


#define int i64

using vi = vector<int>;
using pii = pair<int,int>;

i32 main(){
	ios::sync_with_stdio(false), cin.tie(nullptr);
	mt19937_64 rd(time(0));

	int n;
	cin >> n;
	vi valA(n + 1), valB(n + 1);
	for(int i = 1; i <= n; i ++)
		valA[i] = rd(), valB[i] = rd();

	vi cnt(n + 1), a(n + 1), b(n + 1), pre(n + 1);
	for(int i = 1; i <= n; i ++) {
		cin >> a[i];
		cnt[a[i]] ++;
		if(cnt[a[i]] % 3 == 0) b[i] = valA[a[i]];
		if(cnt[a[i]] % 3 == 1) b[i] = valB[a[i]];
		if(cnt[a[i]] % 3 == 2) b[i] = valA[a[i]] ^ valB[a[i]];
		pre[i] = pre[i - 1] ^ b[i];
	}

	cnt = vi(n + 1);
	map<i64,i32> sum;
	sum[0] = 1;
	int res = 0;
	for(int l = 0 , r = 1; r <= n; r ++) {
		cnt[a[r]] ++;
		while(cnt[a[r]] > 3) {
			cnt[a[l]] --;
			if(l > 0) sum[pre[l - 1]] --;
			l ++;
		}
		res += sum[pre[r]], sum[pre[r]] ++;
	}
	cout << res << "\n";
	return 0;
}

标签:pre,Educational,Rated,int,valB,valA,Codeforces,cnt,sum
From: https://www.cnblogs.com/PHarr/p/18445826

相关文章

  • Codeforces Round 976 (Div. 2)
    C.BitwiseBalancing(C)先求出\(b-c\)的值,再考虑\(a\)的每个二进制位取0或1对答案的影响。vp的时候不知道为什么错了很多次。voidsolve(){llb,c,d;scanf("%lld%lld%lld",&b,&c,&d);if(b-c>d){printf("-1\n");retur......
  • Codeforces Round 976 (Div. 2)
    一万五参赛,VP赛时629(唐了,E没想出来)A.FindMinimumOperations简单题。注意特判,用除法统计答案即可。#include<bits/stdc++.h>usingnamespacestd;intT,n,k;intmain(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&k); if(k==1||n......
  • Codeforces Round 976 (Div. 2) 题解
    CodeforcesRound976(Div.2)题解2020B一个常见的想法:开关灯=异或,虽然在这道题里没啥用注意到,第i盏灯的按钮被按的次数就是i的除它本身以外的因子个数而完全平方数的因子数为奇数,其他数的因子数为偶数点击查看更多信息#include<bits/stdc++.h>usingnamespacestd;voi......
  • CodeForces - 118D - dp
    这道题的思路可能来源于步兵后面必须跟骑兵,反之亦然,那么一个兵种当前的状态肯定是由另一个兵种上一个的状态推来的(即取用该当前取用的兵种之前)。接下来就要考虑怎么控制每次取用多少个人了,由题意可知,每次取用不得超过k1或k2,我们从1-n1和从1-n2表示骑兵和步兵当前的数量表示......
  • Codeforces Round 975 (Div. 2)
    一万四参赛,VP赛时60A.MaxPlusSize一定选择最大值,若有多个最大值,优先选在奇数位置的最大值,后间隔涂上红色。#include<bits/stdc++.h>usingnamespacestd;constintN=105;intT,n,a[N];intmain(){ scanf("%d",&T); while(T--){ scanf("%d",&n); intm......
  • Codeforces Global Round 19 E. Best Pair
    \(cnt\)的取值种类数不超过\(\sqrtn\)。因此我们可以枚举\(cnt\)然后贪心选最大的值。#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;#defineinti64usingvi=vector<int>;usingpii=pair<int,int>;voidsolve()......
  • CF2020(Codeforces Round 976 (Div. 2))
    CF2020A.FindMinimumOperations难度:红转换进制,每一位上数字相加。#include<bits/stdc++.h>#definelllonglongusingnamespacestd;llt,n,k,ans;intmain(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>t;while(t--){cin&......
  • Codeforces Round 956 (Div. 2)
    无法评价,不知道是我傻逼还是题傻逼。A.ArrayDivisibility题意让你构造一个长度为\(n\)的序列,满足对于每一个\(i\)\((i\in[1,n])\),让\(a_j\)之和为\(i\)的倍数,\(j\)能被\(i\)整除。换句话说,让你构造一个长度为\(n\)的序列,满足\(\sum_{j|i}a_j\)能被\(i\)......
  • Codeforces2014E Rendez-vous de Marian et Robin(分层图最短路)
    题意给定一个无向图,含有\(n\)个点和\(m\)条边。题解点击查看代码#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;constexpri64inf=1e18;voidsolve(){intn,m,h;cin>>n>>m>>h;vector<vector<......
  • Codeforces Round 974 (Div. 3) - D题
    这道题题意就是你有k个工作,每个工作都有一个时间区间左边界l和右边界r,妈妈和哥哥要来看你,时长为d,题目要求求出1.哥哥看你的这段时间工作时间段重叠最多是多少?2.妈妈看你的这段时间工作时间段重叠最少是多少?这道题如果硬做的话可能就是线段树了(蒟蒻暂时没有想到其他的做法),但如果......