IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> #757 (Div. 2) C(位运算+推式子 D1(dp -> 正文阅读

[C++知识库]#757 (Div. 2) C(位运算+推式子 D1(dp

C. Divan and bitwise operations
题意:
给定一个长度为 n n n 的非负整数序列, m m m 个条件,每次给定区间 [ l , r ] [l,r] [l,r],以及这段区间所有数的或起来的值 x x x。求所有该序列所有子序列的异或和
思路:
题解
题解中 C C C 讲的很好理解
首先先明确长度为 n n n 的序列,子序列有多少个,对于每个数选或不选,显然有 2 n 2^n 2n 个子序列,其中包括了空子序列
把每一位分开考虑
设第 i i i 位有 k k k 1 1 1,则有 n ? k n-k n?k 0 0 0
一个子序列对答案有贡献,需要满足第 i i i 位有奇数个 1 1 1
结合二项式定理,第 i i i 位有奇数个 1 1 1 的子序列的个数: 2 ( n ? k ) ? ( C k 1 + C k 3 + . . . + C k l a s t ) = 2 n ? k ? 2 k ? 1 = 2 n ? 1 2^{(n-k)}*(C_k^1+C_k^3+...+C_k^{last})=2^{n-k}*2^{k-1}=2^{n-1} 2(n?k)?(Ck1?+Ck3?+...+Cklast?)=2n?k?2k?1=2n?1
可以发现答案与 k k k 无关,某一位对答案是否有贡献取决于该位有没有 1 1 1
1 1 1 则会贡献 2 i ? 2 n ? 1 2^i*2^{n-1} 2i?2n?1
这个时候答案就很显然了,把所有 x x x 或一遍,
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 2e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
ll q_pow(ll a, ll b){
	ll ans = 1;
	while(b){
		if(b & 1) ans = ans * a % mod;
		b >>= 1;
		a = a * a % mod;
	}
	return ans;
}
void work()
{
	cin >> n >> m;
	ll ans = 0;
	for(int i = 1, l, r, x; i <= m; ++i){
		cin >> l >> r >> x;
		ans |= x;
	}	
	cout << ans % mod * q_pow(2, n - 1) % mod << endl;
}

int main()
{
	ios::sync_with_stdio(0);
	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}

D1. Divan and Kostomuksha (easy version)
题意:
给定一个正整数序列,现在可以对该序列进行任意排序,使得下列式子最大化
∑ i = 1 n g c d ( a 1 , a 2 , . . . a i ) \sum_{i=1}^ngcd(a_1,a_2,...a_i) i=1n?gcd(a1?,a2?,...ai?)
思路:
考虑 d p dp dp
d p [ i ] dp[i] dp[i] 表示把 g c d gcd gcd i i i 的数放最前时的答案,此时这组数的先后顺序不论, 但是一定是排在其他数之前的.
d [ i ] d[i] d[i] 表示含有因子 i i i 的数的数量
状态转移方程
d p [ i ] = max ? j ∣ i ( d p [ j ] + d [ i ] ? ( i ? j ) ) dp[i]=\max_{j|i}(dp[j]+d[i]*(i-j)) dp[i]=jimax?(dp[j]+d[i]?(i?j))
用类似线性筛的方法转移
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 5e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
int d[maxn];
ll dp[maxn];
void f(int x){
	for(int i = 1; i * i <= x; ++i) if(x % i == 0)
	{
		d[i]++;
		if(i * i != x) d[x/i]++;
	}
}
void work()
{
	cin >> n;
	for(int i = 1, x; i <= n; ++i) cin >> x, f(x);
	ll ans = n;
	dp[1] = n;
	for(int i = 1; i <= maxn - 9; ++i)
	{
		ans = max(ans, dp[i]);
		for(int j = 2; j * i <= maxn - 9; ++j)
		{
			dp[i * j] = max(dp[i * j], dp[i] + 1ll * d[i * j] * (i * j - i));
		}
	}
	cout << ans << endl;
}

int main()
{
	ios::sync_with_stdio(0);
//	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章           查看所有文章
加:2021-12-11 15:32:36  更:2021-12-11 15:35:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:59:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码