csp-s模拟46 set read race
题面:https://www.cnblogs.com/Juve/articles/11556809.html
Set:
题干中说的M个数两两不同是说不能重复选同一个位置的数,而不是不能选数值相同的数,所以不用取重
题目中说是子集,其实连续的序列中就有答案
我们处理出mod N下的前缀和,如果有两个前缀和相同,那么选这两个前缀和中间的数即可,因为减完之后余数为0
这样一定能保证正确吗?或者一定存在两个前缀和相等的情况吗?
在mod N先前缀和最多有0~N-1这N种取值,但是一共有N+1个前缀和(sum[0]也算一种),所以一定有答案
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 1000005
#define re register
using namespace std;
int n,sum[MAXN],a[MAXN],pos[MAXN];
inline int read(){
re int x=0;re char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x;
}
signed main(){
n=read();
for(re int i=1;i<=n;++i){
a[i]=read();
sum[i]=(sum[i-1]+a[i]%n)%n;
if(!pos[sum[i]]) pos[sum[i]]=i;
else{
re int j=pos[sum[i]];
printf("%d\n",i-j);
for(re int p=j+1;p<=i;++p){
printf("%d ",p);
}
puts("");
return 0;
}
}
return 0;
}
Read:
一个显然的结论,设数量最多的书出现的次数为k,那么答案就是max(0,2×k-n-1)
但是题目卡空间,不能存下,所以我们要想顺序访问每一个元素就让它从新生成一遍
先扫第一遍,记录一个cnt和id,如果cnt=0,那么cnt=1,id=a[i],
如果id=a[i],cnt++,如果不等,cnt--,那么最终留下的id就是出现次数最多的
然后再扫一遍统计id出现次数即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define re register
using namespace std;
const int MAXN=1005;
int n,m,k,cnt[MAXN],x[MAXN],y[MAXN],z[MAXN],S,id=0,sum=0,ans;
signed main(){
scanf("%d%d",&m,&k);
for(int i=1;i<=m;++i) scanf("%d",&cnt[i]);
for(int i=1;i<=m;++i) scanf("%d",&x[i]);
for(int i=1;i<=m;++i) scanf("%d",&y[i]);
for(int i=1;i<=m;++i) scanf("%d",&z[i]);
S=(1<<k)-1;
for(int i=1;i<=m;++i){
if(sum==0) id=x[i],sum=1;
else if(id==x[i]) ++sum;
else --sum;
long long last=x[i];
for(int j=1;j<cnt[i];++j){
last=(last*y[i]+z[i])&S;
if(sum==0) id=last,sum=1;
else if(id==last) ++sum;
else --sum;
}
}
sum=0;
for(int i=1;i<=m;++i){
n+=cnt[i];
if(x[i]==id) ++sum;
long long last=x[i];
for(int j=1;j<cnt[i];++j){
last=(last*y[i]+z[i])&S;
if(last==id) ++sum;
}
}
ans=max(0,sum*2-n-1);
printf("%d\n",ans);
return 0;
}
Race:
考虑怎么求出 x 的答案 . 平方相当于是枚举两个人 ( 可以相同 ), 把这两个人同时排在 x 前面的天数计入答案 . 那么对于 x, 如果我们求出 f[i] 也就是能力值的二进制中第 i+1 到 M-1 位都和他相等且第 i 位不同的人有多少个 , 那么这些人是否排在他前面只由第 i 位确定 , 一共有 2^(M-1) 天 , 而且不需要从这些人中枚举两个人了 , 因为直接平方即可 . 我们只要枚举 i 和 j, f[i] 这些人和 f[j] 这些人同时排在他前面的天数为2^(M-2), 所以把 2*f[i]*f[j]*2^(M-2) 计入答案 . 具体实现有很多方法 , 可以用 trie 树实现 ,记录trie上每一个节点被访问过的次数,在扫每一个a[i]时,它的f数组就是在当前二进制位上与他这一位相反的数被经过的次数,对于tr[root][p]和tr[root][p^1],因为要xor从0到2M-1,所以当前位xor出与他相反的次数是tr[root][p],和它相同的是tr[root][p^1].
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define int long long
#define re register
using namespace std;
const int MAXN=6000005;
const int mod=1e9+7;
int n,m,tot=1,ans=0,a[MAXN],f[MAXN];
int tr[MAXN][2],s[MAXN*2];
void insert(int val){
int root=1;
for(int i=m-1;i>=0;--i){
int p=(val>>i)&1;
if(!tr[root][p]) tr[root][p]=++tot;
++s[tr[root][p]];
root=tr[root][p];
}
}
int query(int val){
int res=0,root=1;
for(int i=m-1;i>=0;--i){
int p=(val>>i)&1;
f[i]=s[tr[root][p^1]];
for(int j=i;j<m;++j) (res+=(f[i]*f[j])%mod)%=mod;
root=tr[root][p];
}
return (res<<(m-1))%mod;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(re int i=1;i<=n;++i){
scanf("%lld",&a[i]);
insert(a[i]);
}
for(int i=1;i<=n;++i){
ans^=query(a[i]);
}
printf("%lld\n",ans);
return 0;
}
csp-s模拟46 set read race的更多相关文章
- Noip模拟46 2021.8.23
给了签到题,但除了签到题其他的什么也不会.... T1 数数 人均$AC$,没什么好说的,就是排个序,然后双指针交换着往中间移 1 #include<bits/stdc++.h> 2 #d ...
- [NOIP模拟46]鼠树
神仙题. 首先不考虑把黑点变白,发现每个白点的信息与它的归属点是相同的.可以在线段树中只维护黑点的信息,再记录$DFS$序上每个点之前黑点个数的前缀和,每次操作可以二分出该点的归属点进行操作. 具体维 ...
- CSPS模拟 46
勿忘国耻. 由于重新评测我看到了不是很真实的一幕 紧接着是更不真实的一幕 就在虚假形象快要建立完成的时候 它由于来自东方的神秘力量倒塌了 被两个学校的大佬爆踩了(捂脸 T1 无脑背包? 考试时想1h想 ...
- 8.23考试总结(NOIP模拟46)[数数·数树·鼠树·ckw的树]
T1 数数 解题思路 大概是一个签到题的感觉...(但是 pyt 并没有签上) 第一题当然可以找规律,但是咱们还是老老实实搞正解吧... 先从小到大拍个序,这样可以保证 \(a_l<a_r\) ...
- noip模拟46
A. 数数 排好序从两头贪心即可 B. 数树 首先很容易想到容斥 如果选择的边集的相关点集有点的度数大于 \(1\) 是不合法的 也就是说一定形成若干条长度不一的链 要给这些链上的点安排排列中的数,方 ...
- [考试总结]noip模拟46
脑袋确实是不好使了需要回家暴颓治疗 数数数树鼠树 真好玩. 数数 大水题一个,妥妥的签到题目,然后... 我没签上 气展了!!! 其实我还是想麻烦了. 就是我们实际上就是排序之后每一次找头上和尾巴上的 ...
- 多线程案例:龟兔赛跑-Race
多线程案例:龟兔赛跑-Race 前置条件: 首先来个赛道距离,然后要离终点越来越近 判断比赛是否结束 打印出胜利者 龟兔赛跑开始 故事中是乌龟赢了,兔子需要睡觉,所以我们来模拟兔子睡觉 乌龟赢得比赛 ...
- java基础——并发1
一.并发的定义 并发:对于这个概念一直就是没怎么搞懂,就是感觉特别的生疏,(自己从从字面上理解就是多个东西,一起出发),所以就上网上查了一些资料: 同时拥有两个或多个线程,如果程序在单核处理器上运行, ...
- 谈谈java中的并发(一)
一.并发的定义 并发:对于这个概念一直就是没怎么搞懂,就是感觉特别的生疏,(自己从从字面上理解就是多个东西,一起出发),所以就上网上查了一些资料: 同时拥有两个或多个线程,如果程序在单核处理器上运行, ...
随机推荐
- PHP curl采集
if (function_exists('curl_init')) { //检查函数是否存在 $url = "http://***.com/"; $ch = curl_init() ...
- 线性dp,后缀处理——cf1016C好题
绝对是好题 #include<bits/stdc++.h> using namespace std; #define maxn 300005 #define ll long long ll ...
- npm使用入门
NPM使用入门 npm 就是node package manager node的包管理工具 我们通过npm install 模块 来安装模块,缩写:npm i 模块,注意,低版本的node可能需要np ...
- selenium - 截图下载图片
from selenium import webdriver from selenium.webdriver import ChromeOptions from time import sleep f ...
- ICPC 2019 徐州网络赛
ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...
- 第二十一篇:spring怎么做缓存
项目背景:你可能遇情景:1.一个做统计的页面,每次刷新需要调接口做查询 ,是联表查询,查出来的数据还需要做一些计算或者加工,不算页面上的图表插件,刷新一次,延迟个几秒钟才出的来2. 一个统计接口如此 ...
- (function($){….})(jQuery)与$(function(){})的区别
function fun($){…};fun(jQuery);这种方法多用于存放开发的插件,执行其中的代码时,Dom对象并不一定加载完毕. $(function(){})等价于$(document). ...
- SpringMVC的Hello World
本次使用Maven和Spring IO platform创建SpringMVC的Hello World. 一.Maven的Pom文件内容如下: <project xmlns="http ...
- MATLAB 去掉数组里面不要的元素
trainfinger=1 testingfinger=(1:8); testingfinger = testingfinger(~ismember(testingfinger,trainfinger ...
- leetcode146周赛-1130-叶值的最小代价生成树*
题目描述: class Solution(object): def mctFromLeafValues(self, arr): """ :type arr: List[i ...