1.数组异或

(xorarray.pas/c/cpp)

(xorarray.in/out)

时间限制:2s/空间限制:256M

【题目描述】

    xor——异或,和 and 与or 一样,是一种重要的逻辑运算,他的运算规律是 0 xor 0 = 0,1 xor 1 = 0,1 xor 0 = 1,0 xor 1 = 1

  两个整数之间的异或是将两个整数转化成二进制,对他们的每一位分别进行 xor 操作,例:6(110) xor 13(1101) = 11(1011)

  现在我们要介绍一种新的操作——数组异或,将两个相同大小(假设都为n)的数组A、B异或成一个新数组C,则新数组必满足:

  现在给你数组大小n,和两个数组A,B

  求他们的异或数组C

  由于最终答案可能过大,你需要对C的每个元素对109+7取模

【输入格式】(xorarray.in)

  一共3行。

  第一行一个正整数。

  接下来两行每行个正整数,表示数组A、B。

【输出格式】(xorarray.out)

  一共行,个正整数,表示数组C。

【输入输出样例1】

xorarray.in

xorarray.out

7

20670 1316 25227 8316 21095 28379 25235

19745 6535 14486 5460 15690 1796 12403

7583 52096 161325 276944 453024 675974 958287

【数据规模约定】

  对于50%的数据,N≤100

  对于全部的数据,N≤100000

思路:二进制拆分,维护一个二进制前缀和。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100100
#define mod 1000000007
using namespace std;
int n;
int bit[];
int a[MAXN],b[MAXN],c[MAXN];
int suma[MAXN][],sumb[MAXN][];
int finda(int r,int wh){
long long tot=;
for(int i=;i<=;i++)
if(wh&bit[i]) tot=(tot+1ll*(r-suma[r][i])*bit[i])%mod;
else tot=(tot+1ll*suma[r][i]*bit[i])%mod;
return int(tot%mod);
}
int findb(int r,int wh){
long long tot=;
for(int i=;i<=;i++)
if(wh&bit[i]) tot=(tot+1ll*(r-sumb[r][i])*bit[i])%mod;
else tot=(tot+1ll*sumb[r][i]*bit[i])%mod;
return int(tot%mod);
}
int main(){
freopen("xorarray.in","r",stdin);
freopen("xorarray.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
int x=a[i],len=;
while(x){
suma[i][len++]=suma[i-][len]+(x&);
x/=;
}
for(int j=len;j<=;j++) suma[i][j]=suma[i-][j];
}
for(int i=;i<=n;i++){
scanf("%d",&b[i]);
int x=b[i],len=;
while(x){
sumb[i][len++]=sumb[i-][len]+(x&);
x/=;
}
for(int j=len;j<=;j++) sumb[i][j]=sumb[i-][j];
}
bit[]=;
for(int i=;i<=;i++) bit[i]=bit[i-]<<;
c[]=a[]^b[];
for(int k=;k<=n;k++){
c[k]=c[k-];
c[k]=(c[k]+finda(k-,b[k]))%mod;
c[k]=(c[k]+findb(k,a[k]))%mod;
}
for(int i=;i<=n;i++) cout<<c[i]<<" ";
}

2.侦探游戏

(detective.pas/c/cpp)

(detective.in/out)

时间限制:1s/空间限制:256M

【题目描述】

  小W最近沉迷一个侦探游戏,在这个游戏中会不断出现命案,而小W作为主角,需要不断地收集各种关键证据,只有当所有的关键证据都被找到,你才能   驳倒所有人错误的判断,找出真正的凶手。

  一共有个关键证据以及条信息,每条信息如下所示 : 如果你已经掌握了证据 i ,那么你可以通过 k 个时间的搜索和推理得到证据 j ,同样的,如果你掌握了证据 j 你也可以通过 k 个时间得到证据 j 。

  游戏开始时玩家通过初步观察现场已经得到了证据1,于此同时,每个玩家在游戏开始阶段时都能获得一个特殊技能来加快游戏进度,增加趣味性。小 W 选了一个他以前从来没用过的技能 : 好运。这是一个被动技能,系统会在游戏开始时选定一对证据(a,b)当小W发现其中一个证据的时候,他会很好运地立即获得另外一个证据(不计入时间)。

  但是这个技能是完全随机的,小W完全不知道进入游戏后系统会挑选哪一对证据,他希望你能帮助他算出他花在本轮游戏上的时间的期望值,这样他心里能有点B数。

  提供的信息保证 : i不会等于j,每个k值都互不相同,个证据都能被得到。

【输入格式】(detective.in)

  一共行。

  第一行两个正整数,表示证据数量和信息数量。

  接下来行,每行三个数字i,j,k表示一个信息

【输出格式】(xorarray.out)

  一共行,个整数(期望值是实数,但这里请直接保留0位小数输出)

【输入输出样例】

detective.in

detective.out

3

1 2 3

1 3 2

2 3 5

2.3333

【数据规模约定】

  对于的数据,

  对于的数据,

  对于全部的数据,

【样例解释】

  答案应该是2.33333......,取2

以下思路来自xxy大佬的博客

60分做法:

先做一遍最小生成树

枚举两个点i,j,那么替换掉的是最小生成树上i,j路径上权值最大的边

倍增维护

时间复杂度:O(n*n*logn)

100分做法:

换一个角度,考虑被替换掉的边的贡献

边e要想被替换掉,那么点 i,j 要满足两个条件:

① 设e的两端点所连的子树为u,v,i∈u,j∈v

② e的边权是连通 i,j 必经之路(最短路)上边权最大的边

怎么找这条边?——Kruscal算法

Kruscal算法每次找还没有加进去的权值最小的边,所以满足必经之路

还没有加进去的边权最小的边,是已加进去的边权最大的边,所以满足路径上边权最大

所以,设最小生成树的总权值为sum,设当前边权为w,当前边连接的两点的集合大小分别为 s1、s2

ans=(sum*n*(n-1)- 2*Σ s1*s2*w)/(n*(n-1))

n*(n-1):任意选两个点共有这些选法

Σ 前乘2:u,v 和 v,u 算不同的方案

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 20010
#define N 100010
using namespace std;
int n,m;
long long sum,cnt;
int fa[M],size[M];
struct nond{
int u,v,w;
}edge[N];
int cmp(nond a,nond b){
return a.w<b.w;
}
int find(int k){
if(fa[k]==k) return k;
return fa[k]=find(fa[k]);
}
int main(){
freopen("detective.in","r",stdin);
freopen("detective.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
sort(edge+,edge++m,cmp);
for(int i=;i<=n;i++) fa[i]=i,size[i]=;
for(int i=;i<=m;i++){
int dx=find(edge[i].u);
int dy=find(edge[i].v);
if(dx==dy) continue;
fa[dy]=dx;
sum+=edge[i].w;
cnt+=1ll*size[dx]*size[dy]*edge[i].w;
size[dx]+=size[dy];
}
printf("%.2lf",sum-cnt*2.0/(n*(n-)));
}

3.棋盘迷宫

(boardgame.pas/c/cpp)

(boardgame.in/out)

时间限制:5s/空间限制:256M

【题目描述】

  小A和小Z是非常要好的朋友,而且他们都对迷宫游戏非常有兴趣。他们经常在自习课上用迷宫来打发时间(两位都是学习效率400%的dalao,大家切记不要模仿)。

  他们的迷宫非常简单,又被他们叫做是棋盘迷宫,迷宫本身是一个N*M大小的棋盘,从左往右列数不断加大,从上往下行数不断增大,故左上角的坐标为(1, 1),右下角的坐标为(N,M)。当你处在坐标为(X,Y)的格子里时,你只能走到(X+1,Y)或(X,Y+1),即只能往右走或者往下走(当然你也不能走出棋盘)。同时部分格子中有障碍物,这样的格子是不能经过的,用‘#’代表,能正常通行的格子由‘.’代表。

  每一轮游戏先由其中一人选定起点和终点,由另外一个人来完成)。但是他们很快发现,并不是每次都能找到一条从起点到达终点的路径,两位dalao的注意力立刻从游戏转移到了如何快速判断路径是否存在这个问题上。

  当然dalao们瞬间得到了算法,不过他想考考你,如果你能顺利解决,也许就能得到他们两个的签名哦!(据说是最高级别的因果律护身符,能让人逢考必过)

【输入格式】(boardgame.in)

  一共行。

  第一行两个正整数为,表示棋盘迷宫的行列。

  接下来行,每行一个长度为的字符串,由‘#’‘.’两种字符组成

  接下来1行,一个正整数,表示询问的个数

  接下来行,每行四个正整数x1,y1,x2,y2询问点(x1,y1)到(x2,y2)是否有一条合法的路径

  数据保证(x1,y1)(x2,y2)所在的位置都是‘.’,同时x1<=x2,y1<=y2

【输出格式】(boardgame.out)

  一共行,每行一个字符串或者,对应每一个询问的答案。

【输入输出样例】

boardgame.in

boardgame.out

4 4

....

..#.

.##.

....

3

2 2 4 4

2 1 4 4

1 2 4 4

No

Yes

Yes

【数据规模约定】

  对于40%的数据,N,M<=100,Q<=1000

  对于全部的数据,N,M<=500,Q<=1000000

以下思路来自xxy大佬的博客

分治+DP+bitset

若点(x1,y1)能访问到点(x2,y2)

假设x1<=x2,y1<=y2

那么(x1,y1)往右下扩展,(x2,y2)往左上扩展,两个点一定在中间某一行相遇

所以可以利用分治的思想枚举相遇的那一行

如果x1和x2都在枚举的这一行的上面,那就扔到左边

如果x1和x2都在枚举的这一行的下面,那就扔到右边

左边和右边的分别继续分治下去

如果x1和x2一个在上面,一个在下面,那就判断这两个点能否在这一行相遇

能在这一行相遇,两个点一定能相遇

反之,一定不能相遇

如何判断 ?

假设当前枚举的相遇行为mid,

f[i][j][k]=0/1表示第i行第j列的点,向右下扩展,能否扩展到第mid行的第k列

g[i][j][k]=0/1表示第i行第j列的点,向左上扩展,能否扩展到第mid行的第k列

若 f[x1][y1][k] 和 g[i][j][k] 有一个k同时为true,那么两个点就可以相遇

第三维可以用bitset简化

f的转移:

预处理:f[mid][j][j]=第mid行第j列是否有障碍

倒叙枚举mid行之上的i,j,f[i][j]|=f[i][j+1],f[i][j]|=f[i+1][j]

g的转移类似,

正序枚举mid行之下的,加号改成减号即可

#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 501
#define M 1000000
using namespace std;
int n,m,Q;
char s[MAXN];
bool map[MAXN][MAXN],ans[M];
bitset<MAXN>f[MAXN][MAXN],g[MAXN][MAXN];
struct nond{
int sx,sy,tx,ty,id;
}p;
void slove(vector<nond>vec,int l,int r){
if(l>r) return ;
int mid=(l+r)/;
for(int i=mid;i>=l;i--)
for(int j=m;j;j--){
f[i][j]=;
if(!map[i][j]) continue;
if(i==mid) f[i][j].set(j);
else f[i][j]|=f[i+][j];
if(j!=m) f[i][j]|=f[i][j+];
}
for(int i=mid;i<=r;i++)
for(int j=;j<=m;j++){
g[i][j]=;
if(!map[i][j]) continue;
if(i==mid) g[i][j].set(j);
else g[i][j]|=g[i-][j];
if(j!=) g[i][j]|=g[i][j-];
}
vector<nond>vl,vr;
for(vector<nond>::iterator it=vec.begin();it!=vec.end();it++){
p=*it;
if(p.tx<mid) vl.push_back(p);
else if(p.sx>mid) vr.push_back(p);
else ans[p.id]=(f[p.sx][p.sy]&g[p.tx][p.ty]).any();
}
slove(vl,l,mid-);
slove(vr,mid+,r);
}
int main(){
freopen("boardgame.in","r",stdin);
freopen("boardgame.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%s",&s);
for(int j=;j<m;j++)
if(s[j]=='.') map[i][j+]=;
else map[i][j+]=;
}
scanf("%d",&Q);
vector<nond>vec;
for(int i=;i<=Q;i++){
scanf("%d%d%d%d",&p.sx,&p.sy,&p.tx,&p.ty);
p.id=i;
vec.push_back(p);
}
slove(vec,,n);
for(int i=;i<=Q;i++)
if(ans[i]) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
/*
4 4
....
..#.
.##.
....
3
2 2 4 4
2 1 4 4
1 2 4 4
*/

国庆 day 6 下午的更多相关文章

  1. 国庆 day 7 下午

    思路:见博客. #include<iostream> #include<cstdio> #include<cstring> #include<algorith ...

  2. 国庆 day 2 下午

    最大值(max) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一本书,上面有很多有趣的OI问题.今天LYK看到了这么一道题目: 这里有一个长度为n的 ...

  3. 国庆 day 1 下午

    一道图论好题(graph) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图, ...

  4. 国庆 day 3 下午

    a[问题描述] 你是能看到第一题的 friends 呢. ——hja 给你一个只有小括号和中括号和大括号的括号序列,问该序列是否合法.[输入格式] 一行一个括号序列.[输出格式] 如果合法,输出 OK ...

  5. 2018国庆YALI集训游记

    想了想,像之前那样简略地叙述题意和做法,根本没讲清楚,没有任何意义,还不如写写自己的感受. 感觉YALI真的是一所挺不错的学校吧.总是能有一机房的julao轮番吊打你,总是能有集训队的奆佬来给你出dl ...

  6. 2016.10.4初中部下午NOIP普及组比赛总结

    2016.10.4初中部下午NOIP普及组比赛总结 这次的题有些水,只是第四题有点坑. 题目: 比赛:AC+0+AC+50=250 改题:AC+AC+AC+50=350 一.Bill 满地都是水 题目 ...

  7. 票房和口碑称霸国庆档,用 Python 爬取猫眼评论区看看电影《我和我的家乡》到底有多牛

    今年的国庆档电影市场的表现还是比较强势的,两名主力<我和我的家乡>和<姜子牙>起到了很好的带头作用. <姜子牙>首日破 2 亿,一举刷新由<哪吒之魔童降世&g ...

  8. 搞了我一下午竟然是web.config少写了一个点

    Safari手机版居然有个这么愚蠢的bug,浪费了我整个下午,使尽浑身解数,国内国外网站搜索解决方案,每一行代码读了又想想了又读如此不知道多少遍,想破脑袋也想不通到底哪里出了问题,结果竟然是web.c ...

  9. System.DateUtils 3. IsPM、IsAM 判断是否为上、下午

    编译版本:Delphi XE7 function IsPM(const AValue: TDateTime): Boolean; inline;function IsAM(const AValue: ...

随机推荐

  1. BZOJ2161: 布娃娃 整体二分

    Code: #include <cstdio> #include <algorithm> #include <cstring> #include <vecto ...

  2. React 第三天

    第三天 01:在组件中使用style行内对象并封装样式对象: CmtItem.jsx: import React from 'react' //第一层封装 将样式对象和UI结构分离 // const ...

  3. 【BZOJ4826】【HNOI2017】影魔

    题意: Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄. ...

  4. python常见操作的模板

    1.生成要求稀疏度的随机矩阵 import scipy import scipy.sparse import numpy n=10 m=10 density=0.5 matrixformat='coo ...

  5. sz xshell

    yum install lrzsz -y

  6. UT源码+105032014018

    设计佣金问题的程序 commission方法是用来计算销售佣金的需求,手机配件的销售商,手机配件有耳机(headphone).手机壳(Mobile phone shell).手机贴膜(Cellphon ...

  7. 洛谷 P1403 [AHOI2005]约数研究

    怎么会有这么水的省选题 一定是个签到题. 好歹它也是个省选题,独立做出要纪念一下 很容易发现在1~n中,i的因子数是n / i 那就枚举每一个i然后加起来就OK了 #include<cstdio ...

  8. String spilt时转义特殊字符【转】

    在使用String.split方法分隔字符串时,分隔符如果用到一些特殊字符,可能会得不到我们预期的结果. 我们经常使用public String[] split(String regex)方法来拆分一 ...

  9. 插入排序、冒泡排序、选择排序、希尔排序、高速排序、归并排序、堆排序和LST基数排序——C++实现

    首先是算法实现文件Sort.h.代码例如以下: <pre name="code" class="java">/* * 实现了八个经常使用的排序算法: ...

  10. 手动配置三大框架整合:Spring+Struts2+mybatis

    如今主流的项目框架中,数据库持久层有可能不是hibernate,而是mybatis或者ibatis,事实上它们都是一样的,以下我来把环境搭建一下: [导入相关jar包]新建web项目projectms ...