首页 > 其他分享 >ABC 384 F

ABC 384 F

时间:2024-12-14 22:20:06浏览次数:9  
标签:25 ABC sum 384 ans displaystyle define

ABC 384 F

abc 经典 EF 出式子题。

问题陈述

对于正整数 \(x\) ,定义 \(f(x)\) 如下:"当 \(x\) 是偶数时,继续除以 \(2\) 。经过这些除法后, \(x\) 的最终值为 \(f(x)\) "。例如, \(f(4)=f(2)=f(1)=1\) 和 \(f(12)=f(6)=f(3)=3\) 。

已知长度为 \(N\) 的整数序列 \(A=(A_1,A_2,\ldots,A_N)\) ,求 \(\displaystyle \sum_{i=1}^N \sum_{j=i}^N f(A_i+A_j)\) 。

做法

首先原式可以转化为算 \(\displaystyle \sum_{i=1}^N \sum_{j=1}^N f(A_i+A_j)\) ,然后再算 \(\displaystyle \sum_{i=1}^N f(A_i+A_i)\)。

这是个经典的trick。

然后这个式子不是很好算贡献。

我们将其写为:\(\displaystyle \sum_{i=1}^N \sum_{j=1}^N \frac{a_i+a_j}{2^k}\)

其中 \(k\) 是 \(a_i+a_j\) 的因数中最大二次幂的幂次,也就是 \(lowbit(a_i + a_j) = 2^k\)。

将 \(k\) 提到前面算贡献

\[\sum ^{25}_{k=1} \frac{1}{2^k}( \sum _{i=1}^n \sum _{j=1}^n (a_i+a_j)*[lowbit(a_i+a_j) = 2^k]) \]

设 \(ans_i\) 表示满足 \(lowbit(a_i + a_j) = 2^i\) ,的所有配对 \((a_i,a_j)\) 的和。

原式等于

\[\sum ^{25}_{k=1} \frac{1}{2^k}ans_k \]

考虑如何计算 \(ans_i\)。

我们可以先计算一个 \(f_i\) ,表示所有 \((a_i + a_j) \mod 2^i = 0\) 的 \((a_i+a_j)\) 的和。

这个非常好算,\(O(n \log V)\) 即可算出。

具体来说,枚举 \(i = [0,25]\),令 \(a_i\mod 2^i \rightarrow a_i\),拿一个桶记一下就做完了。

然后我们发现 \(ans_i = f_i -f_{i+1}\)。

证明也是显然的。

在所有因数含有 \(2^i\) 次方的集合中,除去能整除 \(2^{i+1}\) 的,则剩下的便刚好是 \(lowbit(a_i+a_j)=2^i\) 的了。

于是就做完了。

// Problem: F - Double Sum 2
// Contest: AtCoder - Toyota Programming Contest 2024#12(AtCoder Beginner Contest 384)
// URL: https://atcoder.jp/contests/abc384/tasks/abc384_f
// Memory Limit: 1024 MB
// Time Limit: 4000 ms
// Author: Eason
// Date:2024-12-14 20:34:44
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define re register
#define int ll
#define PII pair<int,int>
#define rep(k,a,b) for (int k = a;k <= b;k++)
#define adde(a,b) v[a].push_back(b)
#define addev(a,b,c) v[a].push_back({b,c});
#define rd read
int read()
{
	int f=1,k=0;char c = getchar();
	while(c <'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')k=(k<<1)+(k<<3)+(c^48),c=getchar();
	return k*f;
}

const int N = 2e5+5,M = 5e7 +5;

int pw2[30];
int n;
int a[N];
int sum[30];
int cnt[M];
int ct[M];
int tp[N];


void solve()
{
	cin >> n;
	
	rep(i,1,n) tp[i] = a[i] = rd();
	
	for (int i = 25;i >= 0;i--)
	{
		int mm = (1<<i);
		rep(i,0,mm) cnt[i] = ct[i] = 0;
		for (int i =1;i <= n;i++) a[i] = tp[i] % mm,cnt[a[i]]+=tp[i],ct[a[i]]++;
		for (int j = 1;j < mm;j++)
		{
			if (ct[j] && ct[mm-j])
			sum[i] += cnt[j]*ct[mm-j] + ct[j]*cnt[mm-j];
		}			
		if (ct[0])
		sum[i] += cnt[0] *ct[0]*2;
	}

	int ans = 0;
	for (int i = 25;i >= 0;i--)
	{
		ans += (sum[i]-sum[i+1])/(1<<i);
	}
	int S = 0;
	for (int i = 1;i <= n;i++) 
	{
		int cnt = 0;
		int x = tp[i];
		while (x %2 == 0) cnt++,x/=2;
		ans -= x;
		S += x;
	}
	ans /=2;
	
	ans += S;
	cout << ans << endl;
}

signed main()
{
	int t;t = 1;
	while(t--)
	{
		solve();
	}
	return 0;
}

标签:25,ABC,sum,384,ans,displaystyle,define
From: https://www.cnblogs.com/codwarm/p/18607348

相关文章

  • AT_kupc2019_g ABCのG問題题解
    这题的难度不怎么好说,不过我认为还是挺简单的。我们可以把答案看成由多个子图构成的图,这样我们只需要手打一个小子图,从中推出完整的答案。-把小于子图范围的地方填上子图的字母-如果这个点的横坐标或纵坐标小于子图范围就填上$T_{i,0}$或$T_{0,j}$详见注释intmain(){......
  • 2、多线程-三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC
    题目三个线程分别打印A,B,C,要求这三个线程一起运行,打印n次,输出形如“ABCABCABC....”的字符串代码示例publicclassZeroEvenOdd{ privateintn; privateAutoResetEventaEvent=newAutoResetEvent(true);//一开始A可以运行 privateAutoResetEventbEvent=new......
  • 题解:AT_abc193_f [ABC193F] Zebraness
    题解:AT_abc193_f[ABC193F]ZebranessTag网络流Solution我们要求相邻格子颜色不同的最多个数,可以转化为总边数减去相邻格子颜色相同的最少个数。我们发现颜色相同这一性质很难建图,所以我们将原图黑白染色,染后将黑色格子的原本颜色反转,这样就保证了原本相邻的颜色相同格子变为......
  • ABC381 C-E题解
    C-11/22Substring枚举每个/,从/出发向左右两边扩展到最远。因为每个点最多能被访问一次(向右只扩展2,向左只扩展1),复杂度为\(O(n)\)。intans=0;for(inti=0;i<n;i++){if(s[i]!='/')continue;intl=i-1,r=i+1,len=1;while(l>=......
  • [题解](更新中)AtCoder Beginner Contest 383(ABC383) A~E
    A-Humidifier1照题意模拟即可,时间复杂度\(O(n)\)。点击查看代码#include<bits/stdc++.h>#defineintlonglong#defineN110usingnamespacestd;intn,t[N],v[N],sum;signedmain(){ cin>>n; for(inti=1;i<=n;i++)cin>>t[i]>>v[i]; for(inti=1......
  • 【Atcoder】【ABC383】A- Humidifier 1加湿器 题解
    前言不知道大家有没有关注过AtCoder这是小日子那边的一个网站,每周都会有比赛比起CF等等,最大的优点就是延迟低,题目质量也不错计划以后每周更新题解了正文题目传送门A-Humidifier1题目大意有一个加湿器,给定有次操作,第次在时间加入胜水然而,如果加湿器里有水,它每个单......
  • AT_arc188_a [ARC188A] ABC Symmetry 题解
    容易发现一个串是好的的充要条件是:A,B,C出现次数的奇偶性都相同。因此我们也可以将所有的串分为四类:好的,只有A和其他两个的奇偶性不同,只有B和其他两个的奇偶性不同,只有C和其他两个的奇偶性不同。大于\(k\)的不好统计,可以直接用总数减去小于\(k\)的总和。设$f_{i,x,......
  • ABC383E 题解
    ABC383E题解题意给定一张包含\(n\)个节点和\(m\)条无向带权边的图,以及两个序列\(A_k,B_k\)分别表示图中的某些节点,定义\(f(A_i,B_j)\)为从\(A_i\)到\(B_j\)所有路径各自包含的边权最大值中的最小值,可以任意排列\(B\)中的元素,使得\(\sum_{i=1}^kf(A_i,B_i)\)最......
  • ABC382 C-F题解
    C-KaitenSushi把寿司都放到一个堆里,从前往后扫\(A\)数组,如果当前食客\(A_i\)小于等于堆顶,就取出堆顶,记录这份寿司被第\(i\)个人吃掉。复杂度\(O(n\logm)\)。D-KeepDistance搜索回溯,但每一步从\(10\)枚举到\(m\)会超时,剪一下枝for(inti=10;res.back()+......
  • 题解:AtCoder Beginner Contest AT_abc380_d ABC380D Strange Mirroring
    题目大意给定一个字符串$S$,执行$10^{100}$次以下操作:首先,令字符串$T$为字符串$S$中所有大写字母变为小写字母,小写字母变为大写字母的结果。其次,将$T$拼接在$S$后面。接下来,有一些询问:请输出在所有操作执行完成之后$S$的第$K$个字母。思路乍一看,好大的数......