首页 > 其他分享 >QOJ 5019 整数

QOJ 5019 整数

时间:2023-09-25 11:44:59浏览次数:45  
标签:typedef int 5019 long 整数 QOJ define

QOJ 传送门

考虑从低位向高位 dp,设 \(f_{i, S}\) 为考虑到从低到高第 \(i\) 位,当前每个数超出上界的情况为 \(S\)。

转移可以枚举这一位填的数:

  • 若 \(a_j = 0, r_j = 1\),那么这一位一定不会超出上界;
  • 若 \(a_j = 1, r_j = 0\),那么这一位一定会超出上界。
  • 否则情况和之前相同。

容易发现,若 \(r_j = 1\),相当于做按位与,否则是按位或。做 FWT 即可。

code
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 20;
const int maxm = (1 << 18) + 50;
const ll mod = 998244353;

ll c[maxn];
int f[maxm], g[maxm], h[maxm], n, m, b[maxm];

inline void upd(int &x, int y) {
	((x += y) >= mod) && (x -= mod);
}

inline void FWT(int *a, int op, int d) {
	for (int k = 1, t = 0; k < m; k <<= 1, ++t) {
		for (int i = 0; i < m; i += (k << 1)) {
			for (int j = 0; j < k; ++j) {
				if (c[t] & (1LL << d)) {
					upd(a[i + j], op == 1 ? a[i + j + k] : mod - a[i + j + k]);
				} else {
					upd(a[i + j + k], op == 1 ? a[i + j] : mod - a[i + j]);
				}
			}
		}
	}
}

void solve() {
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%lld", &c[i]);
	}
	m = (1 << n);
	for (int i = 0, x; i < m; ++i) {
		scanf("%1d", &x);
		b[i] = x;
	}
	h[0] = 1;
	for (int d = 0; d < 60; ++d) {
		for (int i = 0; i < m; ++i) {
			f[i] = h[i];
			g[i] = b[i];
		}
		FWT(f, 1, d);
		FWT(g, 1, d);
		for (int i = 0; i < m; ++i) {
			f[i] = 1LL * f[i] * g[i] % mod;
		}
		FWT(f, -1, d);
		for (int i = 0; i < m; ++i) {
			h[i] = f[i];
		}
	}
	printf("%d\n", h[0]);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:typedef,int,5019,long,整数,QOJ,define
From: https://www.cnblogs.com/zltzlt-blog/p/17727613.html

相关文章

  • QOJ 5089
    你细品巨大多太阳的题解,虽然看不懂,但是发现挺有道理的。容易发现,一个无向图是可环覆盖图,当且仅当所有点的度数为偶数。所以将一条边\((u,v)\)看作集合\(\{u,v\}\),相当于求选出\(i\in[0,m]\)个集合\(\{u_i,v_i\}\),其对称差为\(\varnothing\)的方案数。考虑集合幂级数,由......
  • 算法题——定义一个方法自己实现 toBinaryString 方法的效果,将一个十进制整数转成字符
    用除基取余法,不断地除以基数(几进制,基数就是几)得到余数,直到商为0,再将余数倒着拼起来即可。privatestaticStringtoBinaryString(intnumber){StringBuildersb=newStringBuilder();while(true){if(number==0)break;intyushu=num......
  • shell整数计算器
    #!/bin/bashcheckInt(){arr=$1foriin"${arr[@]}";dotemp=`echo$i|sed's/[0-9]//g'|sed's/[]*//g'`if[-n"$temp"];thenecho"$imustbeinteger"return1fid......
  • 字符'1'和整数1的区别
    字符'1'和整数1的区别━━━━━━━━━━━━━━━━━━━━━━字符'1'是一个符号,在内存中以ASCII码对应的二进制00110001存放;整数1是一个数字,在内存中以数字1的二进制的补码00000001存放。......
  • 不使用第三个变量交换两个整数a,b的值
    //题目:不使用第三个变量交换两个整数a,b的值inta=2;intb=5;//第一种方式//a=a+b;//b=a-b;//a=a-b;//txta.Text=a.ToString();//txtb.Text=b.ToString(......
  • QOJ61 Cut Cut Cut! 题解
    题面。题解假设\(1\)号点有\(d\)条出边,给\(d\)条出边赋\(d\)个独立的单位向量,接下来,每个出边记作入边的随机线性组合,那么对于第\(i\)个点,答案就是入边生成的线性空间的秩。正确性证明:对于每个点考虑,假设现在考虑\(i\)号点,将其入边集合记作\(E1_{i}\),出边集合记......
  • 《剑指Offer》-21-调整数组顺序使奇数位于偶数前面
    第一想法是双指针,一个指针用于遍历,一个指针用于标记奇数和偶数的分界,而调整位置则通过交换来实现思路来自于快排代码,分隔指针+交换,也算是双指针? vector<int>exchange(vector<int>&nums){ //一个遍历指针,一个分隔指针,odd指向第一个偶数 intodd=0; for(inti=0;i......
  • 自动检测MultiIndex的维数并全部转化为整数
    将pd.MultiIndex.from_tuples(  [(int(a),int(b))fora,binmy_df.index],  names=my_df.index.names)改写为自动检测MultiIndex的维数并全部转化为整数的函数importpandasaspdimportnumpyasnp#YouroriginalDataFramemy_df=pd.DataFrame(np.add......
  • python 如何将不完全连续的整数序列按[1-5,6,8-10]的格式输出,给出函数代码
    python如何将不完全连续的整数序列按[1-5,6,8-10]的格式输出,给出函数代码defformat_integer_sequence(seq):formatted_seq=[]start=Noneend=Nonefornuminsorted(seq):ifstartisNone:start=numend=num......
  • 2023-09-16:用go语言,给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p , 它们表示
    2023-09-16:用go语言,给你一个整数n和一个在范围[0,n-1]以内的整数p,它们表示一个长度为n且下标从0开始的数组arr,数组中除了下标为p处是1以外,其他所有数都是0。同时给你一个整数数组banned,它包含数组中的一些位置。banned中第i个位置表示arr[banned[i......