实际得分:100+0+0=100

T1

右上角是必败态,然后推下去

发现同行全是必胜态或全是必败态,不同行必胜必败交叉

列同行

所以n,m 只要有一个是偶数,先手必胜

#include<cstdio>

using namespace std;

int main()
{
freopen("star.in","r",stdin);
freopen("star.out","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n) return ;
if(!(n&) || !(m&)) puts("Yuri");
else puts("Chito");
}
}

T2

k=1 暴力:

可持久化trie树 求 异或最大值

#include<cstdio>
#include<iostream>
#include<algorithm> #define N 50001 const int mod=1e9+; using namespace std; int bit[]; int a[N]; int root[N],ch[N*][],cnt[N*],tot; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void insert(int pre,int &now ,int dep,int x)
{
if(!now) now=++tot;
cnt[now]=cnt[pre]+;
if(dep<) return;
int p= (x&bit[dep])>;
ch[now][p^]=ch[pre][p^];
insert(ch[pre][p],ch[now][p],dep-,x);
} int query(int pre,int k,int dep,int x)
{
if(dep<) return ;
int p= (x&bit[dep])>;
if(cnt[ch[k][p^]]-cnt[ch[pre][p^]]) return bit[dep]+query(ch[pre][p^],ch[k][p^],dep-,x);
return query(ch[pre][p],ch[k][p],dep-,x);
} int main()
{
freopen("war.in","r",stdin);
freopen("war.out","w",stdout);
bit[]=;
for(int i=;i<=;++i) bit[i]=bit[i-]<<;
int n,k;
read(n); read(k);
for(int i=;i<=n;++i)
{
read(a[i]);
insert(root[i-],root[i],,a[i]);
}
int ans=;
for(int i=;i<=n;++i) ans=max(ans,query(root[],root[n],,a[i]));
cout<<ans%mod;
}

所有数不超过1023暴力:

预处理所有 i^j的结果,cnt[i]表示第i个数的个数

这样每一种 异或 值出现的次数=cnt[i]*cnt[j]

从大到小枚举,直至k个即可

#include<cstdio>
#include<iostream>
#include<algorithm> #define N 50001 const int mod=1e9+; using namespace std; int cnt[]; struct node
{
int i,j,y;
}e[*+]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} bool cmp(node p,node q)
{
return p.y>q.y;
} int main()
{
freopen("war.in","r",stdin);
freopen("war.out","w",stdout);
int n,x; long long k;
read(n); scanf("%I64d",&k);
for(int i=;i<=n;++i) read(x),cnt[x]++;
int tot=;
for(int i=;i<;++i)
for(int j=i+;j<;++j)
e[++tot].i=i,e[tot].j=j,e[tot].y=i^j;
sort(e+,e+tot+,cmp);
int ans=;
for(int i=;i<=tot;++i)
{
ans=(ans+min(k,1ll*cnt[e[i].i]*cnt[e[i].j])*e[i].y%mod)%mod;
k-=min(k,1ll*cnt[e[i].i]*cnt[e[i].j]);
if(!k) break;
}
cout<<ans;
}

满分做法:

二分出一个最大的t,t满>t的数至少有k个

然后查询所有异或值 >t 的数的和,最后在减去 属于前k大的数的和

二分检验与查询均在trie树上进行

查询>t的数的个数:

枚举n个数a[i],累积 与每一个a[i] 异或后 >t 的个数

对于每一个a[i],设现在是第j位

如果t的第j位是0,那么累加第j位与a[i] 不同 的数的个数,trie树上的当前位置转到 第j位与a[i] 的第j位相同的位置

因为所以在第j位就分出大小的数都以累加,继续找第j位分不出大小的数

如果t的第j位是1,什么都不累加,trie树上的当前位置 转到 第j位与a[i] 不同的 位置

因为如果这一位与t的第j位相同,异或得0,一定<t,如果不同,第j位 分不出大小,继续往后走

累积所有>t的数的和:

还是枚举n个数a[i],累积 与每一个 a[i] 异或后>t 的数的和

累积方法思路与上面差不多

如果t的第j位是0,那么就累计 当前位置 所有的与a[i] 异或 为1的数的和,当前位置转到 与a[i]的第j位相同的位置

如果t的第j为是1,那么当前位置 转到与a[i]的第j位不同的位置

注意每一对合法的数会使用两次,所以累计个数 和 总和 时 注意 除以2

#include<cstdio>
#include<iostream> using namespace std; #define N 50001 const int mod=1e9+;
const int inv=5e8+; long long k; int n; int a[N],trie[N*][],all[N*][],tot=; int cnt[N*]; int bit[]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void insert(int x)
{
int now=,d;
for(int i=;i>=;--i)
{
d=(x&bit[i])>;
if(!trie[now][d]) trie[now][d]=++tot;
now=trie[now][d];
cnt[now]++;
for(int j=;j>=;--j)
if(x&bit[j]) all[now][j]++;
}
} int upper(int x,int t)
{
int pos=,d,sum=;
for(int i=;i>=;--i)
{
d=(x&bit[i])>;
if(!(t&bit[i])) sum+=cnt[trie[pos][d^]],pos=trie[pos][d];
else pos=trie[pos][d^];
// if(t==754974719 && x==962029906) cout<<i<<' '<<sum<<' '<<trie[pos][d^1]<<'\n';
}
return sum;
} int query(int x,int t)
{
int pos=,d,sum=;
for(int i=;i>=;--i)
{
d=(x&bit[i])>;
if(!(t&bit[i]))
{
for(int j=;j>=;--j)
if(x&bit[j]) sum=(sum+1LL*(cnt[trie[pos][d^]]-all[trie[pos][d^]][j])*bit[j]%mod)%mod;
else sum=(sum+1LL*all[trie[pos][d^]][j]*bit[j]%mod)%mod;
pos=trie[pos][d];
}
else pos=trie[pos][d^];
}
//cout<<sum<<'\n';
return sum; } long long check(int x)
{
long long sum=;
for(int i=;i<=n;i++)
{
sum+=upper(a[i],x);
//if(x==754974719) cout<<i<<' '<<sum<<'\n';
}
return sum/;
} int main()
{
freopen("war.in","r",stdin);
freopen("war.out","w",stdout);
read(n); scanf("%I64d",&k);
bit[]=;
for(int i=;i<=;++i) bit[i]=bit[i-]<<;
for(int i=;i<=n;++i)
{
read(a[i]);
insert(a[i]);
// cout<<i<<' '<<tot<<'\n';
}
int l=,r=,mid,tmp=-;
while(l<=r)
{
mid=l+r>>;
if(check(mid)>=k) l=mid+,tmp=mid;
else r=mid-;
// cout<<mid<<' '<<check(mid)<<'\n';
}
int ans=;
if(tmp!=-)
{
long long res=k-check(tmp);
for(int i=;i<=n;i++)
{
ans+=query(a[i],tmp),ans%=mod;
// cout<<ans<<'\n';
}
ans=1LL*ans*inv%mod;
ans=(ans+1LL*res*(tmp+)%mod)%mod;
}
else
{
for(int i=;i<=n;i++) ans+=query(a[i],),ans%=mod;
ans=1LL*ans*inv%mod;
}
cout<<ans;
//for(int i=1;i<=tot;i++) cout<<i<<' '<<cnt[i]<<'\n';
}

T3

因为k<=10 所以线段树维护区间前10大

合并的时候,用了类似于归并排序时用的 两个指针,扫一遍即可

#include<cstdio>
#include<cstring>
#include<iostream> using namespace std; #define N 100001 int f[N<<]; struct node
{
int mx[]; node() { memset(mx,,sizeof(mx));} node operator + (node p)
{
node t;
int a=,b=,c=;
while(c<=) t.mx[c++]=mx[a]>p.mx[b] ? mx[a++] : p.mx[b++];
return t;
}
}tr[N<<]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void build(int k,int l,int r)
{
if(l==r) { read(tr[k].mx[]); return; }
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
tr[k]=tr[k<<]+tr[k<<|];
} void down(int k)
{
f[k<<]+=f[k];
f[k<<|]+=f[k];
for(int i=;i<=;++i)
{
if(tr[k<<].mx[i]) tr[k<<].mx[i]+=f[k];
if(tr[k<<|].mx[i]) tr[k<<|].mx[i]+=f[k];
}
f[k]=;
} node query(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr) return tr[k];
if(f[k]) down(k);
int mid=l+r>>;
if(opr<=mid) return query(k<<,l,mid,opl,opr);
if(opl>mid) return query(k<<|,mid+,r,opl,opr);
return query(k<<,l,mid,opl,opr)+query(k<<|,mid+,r,opl,opr);
} void change(int k,int l,int r,int opl,int opr,int w)
{
if(l>=opl && r<=opr)
{
for(int i=;i<=;i++)
if(tr[k].mx[i]) tr[k].mx[i]+=w;
f[k]+=w;
return;
}
if(f[k]) down(k);
int mid=l+r>>;
if(opl<=mid) change(k<<,l,mid,opl,opr,w);
if(opr>mid) change(k<<|,mid+,r,opl,opr,w);
tr[k]=tr[k<<]+tr[k<<|];
} int main()
{
freopen("noname.in","r",stdin);
freopen("noname.out","w",stdout);
int n,m;
read(n); read(m);
build(,,n);
int op,l,r,w;
while(m--)
{
read(op); read(l); read(r); read(w);
if(!op)
{
if(r-l+<w) cout<<-<<'\n';
else cout<<query(,,n,l,r).mx[w]<<'\n';
}
else change(,,n,l,r,w);
}
}

错误:

将前10大全部放到一个结构体里,query时直接返回结构体

合并的时候 重载的 加号 运算符

所以 标记 不能放到 结构体里

下传标记的时候,只传前10大,但应先判断是否具有第i大

2017 清北济南考前刷题Day 3 morning的更多相关文章

  1. 2017 清北济南考前刷题Day 7 afternoon

    期望得分:100+100+30=230 实际得分:100+100+30=230 1. 三向城 题目描述 三向城是一个巨大的城市,之所以叫这个名字,是因为城市中遍布着数不尽的三岔路口.(来自取名力为0的 ...

  2. 2017 清北济南考前刷题Day 1 afternoon

    期望得分:80+30+70=180 实际得分:10+30+70=110 T1 水题(water) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK出了道水 ...

  3. 2017 清北济南考前刷题Day 3 afternoon

    期望得分:100+40+100=240 实际得分:100+40+100=240 将每个联通块的贡献乘起来就是答案 如果一个联通块的边数>点数 ,那么无解 如果边数=点数,那么贡献是 2 如果边数 ...

  4. 2017 清北济南考前刷题Day 4 afternoon

    期望得分:30+50+30=110 实际得分:40+0+0=40 并查集合并再次写炸... 模拟更相减损术的过程 更相减损术,差一定比被减数小,当被减数=减数时,停止 对于同一个减数来说,会被减 第1 ...

  5. 2017 清北济南考前刷题Day 7 morning

    期望得分:100+50+20=170 实际得分:10+50+20=80 1. 纸牌 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真眼可以看到所有牌朝上的一面和朝下的 ...

  6. 2017 清北济南考前刷题Day 6 afternoon

    期望得分:100+100+30=230 实际得分: 正解: 枚举最高的位,这一位m是1但实际用了0 然后剩余的低位肯定是 正数就用1,负数用0 考场思路:数位DP #include<cstdio ...

  7. 2017 清北济南考前刷题Day 6 morning

    T1 贪心 10 元先找5元 20元 先找10+5,再找3张5 #include<cstdio> using namespace std; int m5,m10,m20; int main ...

  8. 2017 清北济南考前刷题Day 5 afternoon

    期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...

  9. 2017 清北济南考前刷题Day 5 morning

    期望得分:100+100+0=200 实际得分: 坐标的每一位不是0就是1,所以答案就是 C(n,k) #include<cstdio> #include<iostream> ...

随机推荐

  1. 初探Electron

    Electron是什么? 官网是这么描述的:Build cross platform desktop apps with JavaScript, HTML, and CSS 翻译一下:使用JavaSc ...

  2. python xlsxwriter库生成图表的应用

    xlsxwriter可能用过的人并不是很多,不过使用后就会感觉,他的功能让你叹服,除了可以按要求生成你所需要的excel外 还可以加上很形象的各种图,比如柱状图.饼图.折线图等. 请看本人生成的: 这 ...

  3. 漫谈PID——实现与调参

    闲话: 作为一个控制专业的学生,说起PID,真是让我又爱又恨.甚至有时候会觉得我可能这辈子都学不会pid了,但是经过一段时间的反复琢磨,pid也不是很复杂.所以在看懂pid的基础上,写下这篇文章,方便 ...

  4. c# 使用EnyimMemcached 连接memcache

    首先nuget安装EnyimMemcached,本地启动memcache,往app.config(mvc项目则是web.config)加入以下内容: configSection内加入: <sec ...

  5. 解决JSON.stringify()自动将中文转译成unicode的方法

    最近在工作中,发现在IE8下JSON.stringify()自动将中文转译为unicode编码,原本选择的中文字符,传到后台变为了unicode编码,即\u****的形式.查找资料后发现,与标准的JS ...

  6. 我的linux学习之路——(一)

    prompt:命令提示符 命令: command options...... arguments...... 选项: 短选项 长选项 带参数的选项 参数: list----ls 列出,列表 列出制定路 ...

  7. python学习03-数据类型

    一.基本数据类型--数字 布尔型 bool型只有两个值:True和False 之所以将bool值归类为数字,是因为我们也习惯用1表示True,0表示False. 以下是布尔值是False的各种情况: ...

  8. [Luogu 2642] 双子序列最大和

    Description 给定一个长度为n的整数序列,要求从中选出两个连续子序列,使得这两个连续子序列的序列和之和最大,最终只需输出最大和.一个连续子序列的和为该子序列中所有数之和.每个连续子序列的最小 ...

  9. R语言-用户细分

    案例:通过使用R语言的聚类算法将用户进行合理的划分,找出对超市贡献度,光临度最高的优质客户,对后期的推广有更深远的影响 1.导入包 library(dplyr) library(reshape2) l ...

  10. Docker + webpack 打包前端项目

    码云代码地址: https://gitee.com/caonimashi/docker_deployment_front_end    构建基础镜像: 1.下载一个 Apline Linux 操作系统 ...