2017/10/12模拟赛总结
来源:互联网 发布:试客联盟软件 编辑:程序博客网 时间:2024/06/05 14:20
题目来自计蒜客2017 NOIP 提高组模拟赛(四)Day1
T1 小X的质数
首先所有质数可以线性筛出来
那么要处理两个质数相乘
不难发现这种情况一定会在线性筛中出现 只要判一下相乘的为质数即可
筛完之后前缀和累一下就可以
#include<bits/stdc++.h>using namespace std;#define N 10000010int pri[N],sum[N];bool mark[N];void Init(){ int i,j,h=0; for (i=2;i<N;i++){ if (!mark[i]) pri[++h]=i,sum[i]=1; for (j=1;j<=h;j++){ int t=i*pri[j]; if (t>=N) break; mark[t]=1; if (!mark[i]) sum[t]=1; if (!(i%pri[j])) break; } } for (i=1;i<N;i++) sum[i]+=sum[i-1];}int main(){ Init(); int Case; scanf("%d",&Case); while (Case--){ int l,r; scanf("%d%d",&l,&r); printf("%d\n",sum[r]-sum[l-1]); } return 0;}
T2 小X的密室
这就是一个有向边且有限制的图
这样也就最多
然后由于边权是1 直接BFS一遍求出到
#include<bits/stdc++.h>using namespace std;#define N 5010#define M 11#define INF (0x3f3f3f3f)struct edge{ int nxt,t,s;}e[6010];int head[N],edge_cnt;void add_edge(int x,int y,int z){ e[edge_cnt]=(edge){head[x],y,z}; head[x]=edge_cnt++;}int n,m,K,a[N];struct P1{ struct poi{ int x,y,dis; }; queue<poi>Q; bool vis[N][1<<M]; void solve(){ int i; Q.push((poi){1,a[1],0}); vis[1][a[1]]=1; while (!Q.empty()){ int x=Q.front().x,y=Q.front().y,z=Q.front().dis; Q.pop(); for (i=head[x];~i;i=e[i].nxt){ int to=e[i].t,val=e[i].s; if ((y&val)^val) continue; int p=y|a[to]; if (vis[to][p]) continue; if (to==n){ printf("%d\n",z+1); return; } vis[to][p]=1; Q.push((poi){to,p,z+1}); } } printf("No Solution\n"); }}P100;int main(){ memset(head,-1,sizeof(head)); scanf("%d%d%d",&n,&m,&K); int i,j; for (i=1;i<=n;i++) for (j=0;j<K;j++){ int x; scanf("%d",&x); if (x) a[i]|=1<<j; } for (i=1;i<=m;i++){ int x,y,t=0; scanf("%d%d",&x,&y); for (j=0;j<K;j++){ int x; scanf("%d",&x); if (x) t|=1<<j; } add_edge(x,y,t); } if (n==1) printf("0\n"); else P100.solve(); return 0;}
T3 小X的佛光
看起来就像一个树链剖分维护区间的裸题
也确实可以写 不过会被卡常
要用BIT维护才可以卡过去= =
#include<bits/stdc++.h>using namespace std;#define N 200010struct edge{ int nxt,t;}e[N<<1];int head[N],edge_cnt;void add_edge(int x,int y){ e[edge_cnt]=(edge){head[x],y}; head[x]=edge_cnt++;}int n,q;struct query{ int a,b,c;}Q[N];struct P1{ struct Binary_Indexed_Tree{ int bit1[N],bit2[N]; void add(int *bit,int i,int x){ while (i<=n){ bit[i]+=x; i+=i&-i; } } int sum(int *bit,int i){ int res=0; while (i){ res+=bit[i]; i-=i&-i; } return res; } void Add(int l,int r,int t){ add(bit1,l,-t*(l-1)); add(bit1,r+1,t*r); add(bit2,l,t); add(bit2,r+1,-t); } int query(int l,int r){ return sum(bit1,r)-sum(bit1,l-1)+sum(bit2,r)*r-sum(bit2,l-1)*(l-1); } }BIT; int top[N],siz[N],fa[N],son[N],dep[N],id[N],dfs_cnt; void dfs(int x,int f){ siz[x]=1; fa[x]=f; dep[x]=dep[f]+1; int i; for (i=head[x];~i;i=e[i].nxt){ int to=e[i].t; if (to==f) continue; dfs(to,x); siz[x]+=siz[to]; if (siz[to]>siz[son[x]]) son[x]=to; } } void dfs1(int x,int tp){ id[x]=++dfs_cnt; top[x]=tp; if (son[x]) dfs1(son[x],tp); int i; for (i=head[x];~i;i=e[i].nxt){ int to=e[i].t; if (to==fa[x] || to==son[x]) continue; dfs1(to,to); } } void Up(int x,int y,int t){ while (top[x]!=top[y]){ if (dep[top[x]]<dep[top[y]]) swap(x,y); BIT.Add(id[top[x]],id[x],t); x=fa[top[x]]; } if (dep[x]<dep[y]) swap(x,y); BIT.Add(id[y],id[x],t); } void solve(){ dfs(1,0); dfs1(1,1); int i; for (i=1;i<=q;i++){ Up(Q[i].a,Q[i].b,1); int ans=0; int x=Q[i].b,y=Q[i].c; while (top[x]!=top[y]){ if (dep[top[x]]<dep[top[y]]) swap(x,y); ans+=BIT.query(id[top[x]],id[x]); x=fa[top[x]]; } if (dep[x]<dep[y]) swap(x,y); ans+=BIT.query(id[y],id[x]); printf("%d\n",ans); Up(Q[i].a,Q[i].b,-1); } }}P100;int main(){ memset(head,-1,sizeof(head)); int num,i; scanf("%d%d%d",&n,&q,&num); for (i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); add_edge(x,y); add_edge(y,x); } for (i=1;i<=q;i++) scanf("%d%d%d",&Q[i].a,&Q[i].b,&Q[i].c); P100.solve(); return 0;}
事实上三个点的分布只有几种情况 分类讨论一下就可以了
不难发现最终的答案就是
#include<bits/stdc++.h>using namespace std;#define N 200010struct edge{ int nxt,t;}e[N<<1];int head[N],edge_cnt;void add_edge(int x,int y){ e[edge_cnt]=(edge){head[x],y}; head[x]=edge_cnt++;}int top[N],siz[N],fa[N],son[N],dep[N],id[N],dfs_cnt;void dfs(int x,int f){ siz[x]=1; fa[x]=f; dep[x]=dep[f]+1; int i; for (i=head[x];~i;i=e[i].nxt){ int to=e[i].t; if (to==f) continue; dfs(to,x); siz[x]+=siz[to]; if (siz[to]>siz[son[x]]) son[x]=to; }}void dfs1(int x,int tp){ id[x]=++dfs_cnt; top[x]=tp; if (son[x]) dfs1(son[x],tp); int i; for (i=head[x];~i;i=e[i].nxt){ int to=e[i].t; if (to==fa[x] || to==son[x]) continue; dfs1(to,to); }}int LCA(int x,int y){ while (top[x]!=top[y]){ if (dep[top[x]]<dep[top[y]]) swap(x,y); x=fa[top[x]]; } return dep[x]<dep[y]?x:y;}int main(){ memset(head,-1,sizeof(head)); int n,q,num,i; scanf("%d%d%d",&n,&q,&num); for (i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); add_edge(x,y); add_edge(y,x); } dfs(1,0); dfs1(1,1); for (i=1;i<=q;i++){ int A,B,C; scanf("%d%d%d",&A,&B,&C); int x=LCA(A,C),y=LCA(B,C),z=LCA(A,B); if (dep[x]<dep[y]) x=y; if (dep[x]<dep[z]) x=z; printf("%d\n",dep[B]+dep[x]-dep[LCA(B,x)]*2+1); } return 0;}
Date:2017/10/13
By CalvinJin
阅读全文
0 0
- 2017/10/12模拟赛总结
- 2017/10/10模拟赛总结
- 2017/10/7模拟赛总结
- 2017/10/9模拟赛总结
- 2017/10/6模拟赛总结
- 2017/10/15模拟赛总结
- 2017/10/16模拟赛总结
- 2017/10/21模拟赛总结
- 2017/10/23模拟赛总结
- 2017/10/25模拟赛总结
- 2017/10/30模拟赛总结
- NOIP2017模拟赛(10) 总结
- 2017/11/3模拟赛总结
- 2017/11/4模拟赛总结
- 2017/11/5模拟赛总结
- 2017/11/6模拟赛总结
- 2017/11/7模拟赛总结
- 2017/11/8模拟赛总结
- LINQ体验(2)——C# 3.0新语言特性和改进(上篇)
- MXNet框架的resize操作
- 机器学习之归一化(Normalization)
- 深度揭秘Twitter的新一代流处理引擎Heron
- LINQ体验(3)——C# 3.0新语言特性和改进(下篇)
- 2017/10/12模拟赛总结
- LINQ体验(4)——LINQ简介和LINQ to SQL语句之Where
- 网络框架Retrofit的Get请求
- Scrollviewindicater
- Exact Low-Rank Matrix Completion from Sparsely Corrupted Entries Via Adaptive Outlier Pursuit
- Tablayout的基础使用
- codevs 1017 乘积最大
- 横向滑动 scorllview
- android同步与异步