首页 > 其他分享 >20240909 加练1

20240909 加练1

时间:2024-09-19 20:25:26浏览次数:1  
标签:tmp 加练 20240909 int sum times 2n ql

目录

比赛链接

link to contest

总结

知识点

B - Festival Decorating

  • \([A_i \neq 0]\) 可以作为多项式卷积里面多项式的系数

  • bitset 可以做01卷积;此时,每一侧都可以作为最外侧所枚举的:

    •   for(int i=1; i<=n; ++i) f.set(x[i]);
        //for(int i=0; i<=m; ++i)
        //	ans[i] = (f & (f>>i)).count();
        //等价写法:
        for(int i=1; i<=n; ++i)
            ans |= f>>x[i];
      
  • bitset 的 _Find_first_Find_next

    •   for(int t=f._Find_first(); t!=f.size(); t=f._Find_next(t))
      

D - Operator Precedence

  • 构造题的方法:“待定系数”、列方程求解

K - Card Game

  • “对所有区间询问”,可以考虑用可持久化线段树预处理“所有区间”的答案

易错点

  • 注意讨论“元素相等”的边界情况(H - Sugar Sweet II)

策略

  • 多想一下再开写(M刚开的时候有好几个思路上的大漏洞)
  • 过题人数与难度不一定正比(G,F 开晚了;K可以开)

题解

B - Festival Decorating

做法1

  • 利用容错性,只需要处理前 \(3^x\) 个元素里能否得到每一个 \(d\)

  • 不考虑颜色就是简单的 FFT。考虑类似于 FFT 做字符串匹配的时候的思路,构造匹配函数:令 \(A_i\) 表示 \(i\) 位置的灯的颜色,没有灯的时候为 0,令 \(B_i = A_i\),只需要计算 \(C_d = \sum_i [A_i > 0][B_{i + d} > 0] (A_i - B_{i+d})^2\)

    • \[ C_d = \sum_i [A_i > 0][B_{i+d} > 0](A_i^2 + B_{i+d}^2 - 2A_iB_{i+d})\\ = \sum_i A_i^2 \cdot \left[ B_{i+d} > 0\right]\\ + \sum_i \left[ A_{i} > 0\right] \cdot B_{i+d}^2\\ - 2 \cdot \sum_i A_i \cdot B_{i+d} \]

做法2

  • bitset,直接从小到大枚举灯的编号 i,设其它的灯出现的位置集合是 f,还没有找到答案的 d 的集合为n_vis,我们拿出 n_vis & (f >> x[i]) 中的所有 1 更新答案即可
  • 如何得到 f
    • 先记录所有灯的位置集合 all
    • 若颜色为 c[i] 的灯数量不超过 \(T\),直接枚举所有同色灯,然后修改all
    • 若颜色为 c[i] 的灯数量超过 \(\sqrt T\),这样的颜色不超过 \(\frac{n}{T}\) 个,预处理该颜色所有灯的位置 g[c[i]] 然后 all ^= g[c[i]]
  • 取 \(T = \sqrt n\) 可以得到 \(O(n \sqrt n + \frac{n^2}{w})\)​ 的复杂度
//https://codeforces.com/group/Ro45Qpwf2L/contest/104976/submission/280692536
const int N = 250010;
int x[N], c[N], n, m;
vector<int> s[N];

bitset<250005> sum, f[1010], nvis, tmp;
int ans[N];
int pos[N], id[N], num;

int main() {
	int q; rd(n), rd(q);
	for(int i=1; i<=n; ++i) {
		rd(x[i]), rd(c[i]);
		m = max(m, x[i]), s[c[i]].PB(x[i]);
	}

	int B = ceil(sqrt(n));
	for(int i=1; i<=n; ++i) if(s[i].size()) {
		for(int v : s[i]) sum.set(v);
		if(s[i].size() > B) {
			id[pos[i] = ++num] = i;
			for(int v : s[i])
				f[num].set(v);
		}
	}

	for(int i=1; i<=m; ++i) nvis.set(i);

	for(int i=1; i<=n; ++i) {
		if(s[c[i]].size() > B)
			tmp = (sum^f[pos[c[i]]]);
		else {
			tmp = sum;
			for(int v : s[c[i]]) tmp.reset(v);
		}
		tmp = (tmp >> x[i]) & nvis;
		for (int t=tmp._Find_first();t!=tmp.size();t=tmp._Find_next(t))
			ans[t] = i, nvis.reset(t);
	}

	while(q--) {
		int d; rd(d);
		printf("%d\n", (int)(ans[d]));
	}
	return 0;
}

D - Operator Precedence

题意:求下列方程的一组解

\[ (a_1 \times a_2) + (a_3 \times a_4) + \cdots + (a_{2n-1}\times a_{2n}) = a_1 \times (a_2 + a_3) \times (a_4 + a_5) \times \cdots \times (a_{2n-2} + a_{2n-1}) \times a_{2n} \]

解:考虑令 \(a_2, a_4 \cdots a_{2n - 2} = 2, a_3, a_5 , \cdots , a_{2n-1} = -1\),设 \(a_1 = x, a_{2n} = y\),则

\[xy = 2x - y -2(n-2) \]

令 \(x=1\) 则 \(y = 3-n\)​,得到一组合法解。

//https://codeforces.com/group/Ro45Qpwf2L/contest/104976/submission/280942688
int main() {
	int ts; rd(ts);
	while(ts--) {
		int n; rd(n);
		if(n == 3) {
			printf("1 -10 6 6 -10 1\n");
			continue;
		}
		print(1), putchar(' ');
		for(int i=2; i<2*n; ++i)
			print(i&1 ? -1 : 2), putchar(' ');
		print(3-n), putchar('\n');
	}
	return 0;
}

K - Card Game

设区间 \([l,r]\) 的答案为 \(ans_{l, r}\),设 \(nxt_i\) 表示 \(a_i\) 在序列中下一次出现的位置。则:

\[ans_{l, r} = \begin{cases} ans_{nxt_l + 1, r} & nxt_l \le r\\ 1 + ans_{l + 1, r} & nxt_l > r \end{cases} \]

用可持久化线段树,由 rt[nxt[l] + 1]rt[l+1] 的一部分,合并得到 rt[l]。具体来说,先找到 [l, nxt[l]], [nxt[l]+1, n] 这两个区间被线段树划分出来的 \(O(\log n)\) 个区间,区间及其祖先新建节点,区间的儿子继承之前的树。

//https://codeforces.com/group/Ro45Qpwf2L/contest/104976/submission/280699787
const int N = 3e5 + 10;
const int M = 60 * N;
int ls[M], rs[M], tg[M];
int ncnt;

int ql, qr, qt;

void upd(int l,int r,int &c, int u, int t) {
	if(!c) c = ++ncnt;
	t += tg[u];
	if(ql <= l && qr >= r) {
		tg[c] += qt + t;
		ls[c] = ls[u], rs[c] = rs[u];
		return;
	}
	int mid = l + r >> 1;
	if(ql <= mid) upd(l, mid, ls[c], ls[u], t);
	if(qr > mid) upd(mid+1, r, rs[c], rs[u], t);
}
 
int qry(int l,int r,int c) {
	if(!c || l == r) return tg[c];
	int mid = l + r >> 1;
	if(ql <= mid) return qry(l, mid, ls[c]) + tg[c];
	else return qry(mid+1, r, rs[c]) + tg[c];
}
 
int rt[N];
 
int n, a[N], p[N], lst[N];
 
int main() {
	int q; rd(n), rd(q);
	for(int i=1; i<=n; ++i) rd(a[i]);
	
	for(int i=1; i<=n; ++i) lst[i] = n+1;
	for(int i=n; i>=1; --i) {
		p[i] = lst[a[i]];
		lst[a[i]] = i;
	}
 
	for(int i=n; i>=1; --i) {
		ql = i, qr = p[i] - 1, qt = 1;
		upd(1, n, rt[i], rt[i + 1], 0);
		ql = p[i], qr = n, qt = 0;
		if(ql <= qr) upd(1, n, rt[i], rt[p[i] + 1], 0);
	}
	int ans = 0;
	while(q--) {
		int l, r; rd(l), rd(r);
		l ^= ans, r ^= ans;
		// printf("query: %d %d\n", l, r);
		ql = r;
		printf("%d\n", ans = qry(1, n, rt[l]));
	}
	return 0;
}

标签:tmp,加练,20240909,int,sum,times,2n,ql
From: https://www.cnblogs.com/zhongyuweis-blog/p/18421254

相关文章

  • 20240909_141725 c语言 整数类型
    整数型重点演练演练关于c99longlong类型是从c99版本开始有的C99是C语言的一个标准版本,全称为ISO/IEC9899:1999,是C语言的一个官方标准化版本,由国际标准化组织(ISO)和国际电工委员会(IEC)联合发布。C99标准在C89/ANSIC(1989年发布的C语言标准)的基础上进行了扩展和更新,引入了......
  • 20240909_151725 c语言 整数扩展
    完整形态类型后根int有无符号unsigned%u使用%u会约束输出无符号数据。如果是一个负数就会显示出错。使用%d可正常显示数据整数小结......
  • 20240909_111725 c语言 关于进位制
    各种进制注意:在较老的版本如VisualStudio2010中,C语言不支持直接使用0b开头来表示二进制数。对于八进制数,如果写成intnum=12;这是十进制的12,如果要明确表示八进制的12,可以写成intnum=012;测一测注,包含了语法错误的情况......
  • 20240909_155524 mysql 三种变量
    什么是变量标识数据的标识符,就是变量变量是标识数据的mysql中的三种变量系统变量自定义变量局部变量系统变量查看所有系统变量showvariables;根据系统变量名查看它的值select@@系统变量名select@@autocommit修改系统变量的值set系统变量名=值setautocommit......
  • 20240909_041725 c语言 代码注释 两种
    两种注释注释示例......
  • 20240909_031725 c语言 执行输出语句的流程
    源代码-》编译后代码-》可执行代码下图为可执行代码的示例路径:......
  • 20240909_011725 c语言 预处理
    在C语言中,第一行#include<stdio.h>是一个预处理指令,用于包含(或说,导入)标准输入输出库(StandardInputOutputLibrary)的头文件。这个库提供了进行输入输出操作的函数,比如printf()用于在屏幕上显示输出,scanf()用于从键盘读取输入等。具体来说:#include是一个预处理指令,告诉编译器......
  • 20240909_021725 c语言 骨架结构
    关注骨架结构明确intmainreturn0的意义与功能......
  • 增加练习(修改获取练习的基本信息接口)
    文章目录1.sun-club-practice-api1.enums1.CompleteStatusEnum.java2.req1.GetPracticeSubjectsReq.java3.vo1.PracticeSubjectListVO.java2.sun-club-practice-server1.PracticeSetController.java2.service1.PracticeSetServiceImpl.java3.dao1.PracticeDao.java......
  • C语言指针介绍加练习
    #指针相关介绍定义    指针(Pointer),通常用于数据的间接访问,指针存储的是指向变量的首地址,16位平台就是2位,如果在32位平台,地址就是4个字节,如果实在64位平台,地址就是8个字节(1Byte=8bit),Int类型4Byte char类型1Byte这个是变量在内存中,分配的地址大小,在内存中一个By......