2017北京国庆刷题Day6 afternoon
期望得分:100+100+40=240
实际得分:100+0+40=140

二进制拆分、二进制前缀和
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
#define N 100001
int a[N],b[N],c[N];
const int mod=1e9+;
int suma[N][],sumb[N][];
int bit[];
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
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);
int n;
scanf("%d",&n);
int len,x;
for(int i=;i<=n;i++)
{
read(a[i]);
len=; x=a[i];
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++)
{
read(b[i]);
len=; x=b[i];
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++) printf("%d ",c[i]);
}


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<algorithm>
#define N 20001
#define M 100001
using namespace std;
typedef long long LL;
int fa[N],siz[N];
struct node
{
int u,v,w;
}e[M];
bool cmp(node p,node q)
{
return p.w<q.w;
}
int find(int i) { return fa[i]==i ? i : fa[i]=find(fa[i]); }
int main()
{
freopen("detective.in","r",stdin);
freopen("detective.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e+,e+m+,cmp);
for(int i=;i<=n;i++) fa[i]=i,siz[i]=;
int u,v;
LL sum=,cnt=;
for(int i=;i<=m;i++)
{
u=find(e[i].u); v=find(e[i].v);
if(u==v) continue;
sum+=e[i].w;
cnt+=1ll*siz[u]*siz[v]*e[i].w;
fa[v]=u; siz[u]+=siz[v];
}
printf("%.2lf",sum-cnt*2.0/(n*(n-)));
}
考场上替换掉的不是 i,j 路径上权值最大的边,替换的是与i,j相连的边权最大的边,0分。
连接i,j 之后,要满足还是一颗树,去掉i,j之间的任意一条边即可


分治+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<cstdio>
#include<vector>
#include<bitset>
#define N 501
#define M 1000001
using namespace std;
int n,m;
bool mp[N][N],ans[M];
char s[N];
bitset<N>f[N][N],g[N][N];
struct node
{
int sx,sy,tx,ty,id;
};
node p;
void solve(vector<node>v,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(!mp[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(!mp[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<node>vl,vr;
for(vector<node>::iterator it=v.begin();it!=v.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();
}
solve(vl,l,mid-);
solve(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++) mp[i][j]= s[j]=='.' ? true : false;
}
int Q;
scanf("%d",&Q);
vector<node>v;
for(int i=;i<=Q;i++)
{
scanf("%d%d%d%d",&p.sx,&p.sy,&p.tx,&p.ty);
p.id=i;
v.push_back(p);
}
solve(v,,n);
for(int i=;i<=Q;i++) ans[i] ? puts("Yes") : puts("No");
return ;
}
考场40分双向宽搜,然而跟普通的bfs一个样
#include<cstdio>
#include<iostream>
using namespace std;
#define N 501
bool mp[N][N];
char s[N];
int n,m,rd[N][N][];
int sx,sy,tx,ty;
int vis[N][N];
int q[N*N],h,t,cnt,bl[N][N];
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
int turn(int i,int j)
{
return (i-)*m+j;
}
bool bfs()
{
cnt++; h=,t=;
q[++h]=turn(sx,sy);
int now,x,y;
vis[sx][sy]=cnt;
vis[tx][ty]=cnt;
q[++t]=turn(tx,ty);
bl[sx][sy]=; bl[tx][ty]=;
while(h<=t)
{
now=q[h++];
x=(now-)/m+; y=now-(x-)*m;
if(bl[x][y]==)
{
if(mp[x+][y])
{
if(bl[x+][y]== && vis[x+][y]==cnt) return true;
if(vis[x+][y]!=cnt) vis[x+][y]=cnt,q[++t]=turn(x+,y),bl[x+][y]=;
}
if(mp[x][y+])
{
if(bl[x][y+]== && vis[x][y+]==cnt) return true;
if(vis[x][y+]!=cnt) vis[x][y+]=cnt,q[++t]=turn(x,y+),bl[x][y+]=;
}
}
else
{
if(mp[x-][y])
{
if(bl[x-][y]== && vis[x-][y]==cnt) return true;
if(vis[x-][y]!=cnt) vis[x-][y]=cnt,q[++t]=turn(x-,y),bl[x-][y]=;
}
if(mp[x][y-])
{
if(bl[x][y-]== && vis[x][y-]==cnt) return true;
if(vis[x][y-]!=cnt) vis[x][y-]=cnt,q[++t]=turn(x,y-),bl[x][y-]=;
}
}
}
return false;
}
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++) mp[i][j]=s[j]=='.' ? true : false;
}
int q;
scanf("%d",&q);
while(q--)
{
read(sx); read(sy); read(tx); read(ty);
if(!mp[sx][sy] || !mp[tx][ty]) { puts("No"); continue; }
if(sx==tx && sy==ty) { puts("Yes"); continue; }
if(tx<=sx && ty<=sy) { puts("No"); continue; }
if(bfs()) puts("Yes");
else puts("No");
}
}
2017北京国庆刷题Day6 afternoon的更多相关文章
- 2017北京国庆刷题Day1 afternoon
期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms Memory Limit:128MB 题目 ...
- 2017北京国庆刷题Day5 afternoon
期望得分:100+60+100=260 实际得分:0+60+40=100 设图中有m个环,每个环有si条边,有k条边不在环中 ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)… ...
- 2017北京国庆刷题Day2 afternoon
期望得分:100+100+50=250 实际得分:100+70+50=220 T1 最大值(max) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一 ...
- 2017北京国庆刷题Day4 afternoon
期望得分:100+100+0=200 实际得分:5+0+0=5 每加入一个数,x的因数位置++ 注意:根号x枚举时,如果x是完全平方数,根号x会重复累计2次,要减去 考场上没减,5分 /(ㄒoㄒ)/~ ...
- 2017北京国庆刷题Day3 afternoon
期望得分:100+0+30=130 实际得分:100+36.5+0=136.5 T3 一个变量写混了,丢了30.. 模拟栈 #include<cstdio> #include<cst ...
- 2017北京国庆刷题Day7 afternoon
期望得分:100+30+100=230 实际得分:60+30+100=190 排序去重 固定右端点,左端点单调不减 考场上用了二分,没去重,60 #include<cstdio> #inc ...
- 2017北京国庆刷题Day6 morning
期望得分:100+100+20=220 实际得分:100+100+20=220 模拟栈 #include<cstdio> #include<cstring> using nam ...
- 2017北京国庆刷题Day7 morning
期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...
- 2017北京国庆刷题Day3 morning
期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...
随机推荐
- 20135313_exp5
课程:Java程序与设计 班级:1353 姓 名:吴子怡 学号:20135313 小组成员: 20135113肖昱 成绩: 指导教师:娄嘉鹏 实验日期:2 ...
- web压力测试_(收集)
作者:ZeldaZzz链接:http://www.zhihu.com/question/19867883/answer/89775858来源:知乎著作权归作者所有,转载请联系作者获得授权. 一个完整的 ...
- map的默认排序和自定义排序
STL的容器map为我们处理有序key-value形式数据提供了非常大的便利,由于内部红黑树结构的存储,查找的时间复杂度为O(log2N). 一般而言,使用map的时候直接采取map<typen ...
- alpha8/10
队名:Boy Next Door 燃尽图 晗(组长) 今日完成 和队友讨论alpha版的最终界面. 明日工作 确定alpha版既定功能的正常使用. 还剩下哪些任务 账号绑定功能以及账单信息的下载. 困 ...
- jQuery之过滤选择器
在原有选择器匹配的元素中进一步进行过滤的选择器 * 基本 * 内容 * 可见性 * 属性 需求 1. 选择第一个div 2. 选择最后一个class为box的元素 3. 选择所有class属性不为bo ...
- (六)Jmeter重要组件的执行顺序及作用域
一.Jmeter重要组件: 1)配置元件---Config Element: 用于初始化默认值和变量,以便后续采样器使用.配置元件大其作用域的初始阶段处理,配置元件仅对其所在的测试树分支有效,如,在同 ...
- (十三)Jmeter之Bean Shell 的使用(二)
该文章来自:http://www.cnblogs.com/puresoul/p/5092628.html 上一篇Jmeter之Bean shell使用(一)简单介绍了下Jmeter中的Bean she ...
- python/django将mysql查询结果转换为字典组
使用python查询mysql数据库的时候,默认查询结果没有返回表字段名称,不方便使用.为了方便使用一般会选择将查询结果加上字段名称以字典组的方式返回查询结果. 实现如下: def dict_fetc ...
- javac和java的使用
java -Xmx128m -Dfile.encoding=gbk -cp ./;bin/;./*;lib/* com.qianlima.crawlOthers.Icp REM REM block e ...
- PHP执行原理
简单解释:PHP执行原理 客户端向服务器发送一个请求,如果请求的是一个HTML页面,服务器直接将HTML页面发送到客户端给浏览器解析,如果请求的是PHP页面,则服务器会运行PHP页面然后生成标准的HT ...