2017广西邀请赛补题
来源:互联网 发布:linux gzip 生成 zip 编辑:程序博客网 时间:2024/04/20 06:05
2017广西邀请赛模拟
传送门
HDU 6182 A Math Problem
数学题。。我和老谭都做过,就交给学弟去做。实际上回忆一下计组的知识,
#include<bits\stdc++.h>#define M(a,b) memset(a,b,sizeof(a))#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int MAXN=100007;typedef long long LL;unsigned long long mp[17];void init(){ for(unsigned long long i=1;i<=16;i++) { unsigned long long ans=1; for(int j=1;j<=i;j++) { ans*=i; } mp[i]=ans; }}int main(){ init(); //for(int i=1;i<=16;i++) // printf("%d:%llu\n", i, mp[i]); int ans=0; unsigned long long n; while(cin>>n) { for(int i=1;i<=15;i++) { if(mp[i]<=n) ans=i; else break; } cout<<ans<<endl; } return 0;}
学弟写A时我在弄C,dfs四元环,简单写了一发MLE。。不知那里写错了了。。学弟找到水题E,求除了某个数以外其他数的and or xor。xor很好办,整体异或在异或被排除的数即可。and和or,数据1e5,暴力统计每一位的1个数,减去特定数字每一位的1,再判断。and某位是1的情况是1的个数==n-1,or某位是1的情况是1的个数>0。sb题WA两发。。
HDU 6186 CS Course
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<map>#include<string>using namespace std;const int MAXN=100007;int sum[35];int a[MAXN];int main(){ int n, q; while(scanf("%d%d", &n, &q)==2) { memset(sum, 0, sizeof(sum)); int xorval=0; for(int i=1;i<=n;i++) { scanf("%d", &a[i]); xorval^=a[i]; for(int j=0;j<30;j++) { if((1<<j)&a[i]) sum[j]++; } } for(int i=1;i<=q;i++) { int kk;scanf("%d", &kk); int andval=0, orval=0; for(int j=0;j<30;j++) { if((1<<j)&a[kk]) { if(sum[j]>1) orval|=(1<<j); if(sum[j]==n) andval|=(1<<j); } else { if(sum[j]>0) orval|=(1<<j); if(sum[j]==n-1) andval|=(1<<j); } } printf("%d %d %d\n", andval, orval, xorval^a[kk]); } } return 0;}
老谭发现数学题后就一直在搞,D题,wa一发后过了。我完全没看。。。
HDU 6185 Covering
#include <cstdio>#include <cstring>#include <algorithm>#define MAXN 6#define LL long longusing namespace std;const LL m=1000000007;struct Matrix{ LL a[MAXN][MAXN]; int r, c;};Matrix ori, res;LL F[5];//F矩阵LL Ans[5];//结果矩阵void init(){ //构造矩阵 ori.r = ori.c = 4; memset(ori.a, 0, sizeof(ori.a)); ori.a[0][0] = ori.a[0][2] = 1; ori.a[0][3] = -1; ori.a[0][1] = 5; ori.a[1][0] = ori.a[2][1] = ori.a[3][2] = 1; //构造单位矩阵 res.r = res.c = 4; memset(res.a, 0, sizeof(res.a)); res.a[0][0] = res.a[1][1] = res.a[2][2] = res.a[3][3] = 1; //构造F矩阵 F[0] = 11, F[1] = 5, F[2] = 1, F[3] = 1;}Matrix muitl(Matrix x, Matrix y){ Matrix z; memset(z.a, 0, sizeof(z.a)); z.r = x.r; z.c = y.c; for(int i = 0; i < x.r; i++) { for(int k = 0; k < x.c; k++) { if(x.a[i][k] == 0) continue; for(int j = 0; j < y.c; j++) z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j]) % m +m) % m; } } return z;}void Matrix(LL n){ while(n) { if(n & 1) res = muitl(ori, res); ori = muitl(ori, ori); n >>= 1; }}void solve(LL n){ Matrix(n);//矩阵的n次幂 对m取余 memset(Ans, 0, sizeof(Ans)); for(int i = 0; i < res.r; i++) { for(int k = 0; k < res.c; k++) Ans[i] = (Ans[i] + res.a[i][k] * F[k]%m +m ) % m; } printf("%lld\n", (Ans[0]+m)%m);}int main(){ LL L; while(scanf("%lld", &L) != EOF) { Ans[0] = 1, Ans[1] = 1, Ans[2] = 5, Ans[3] = 11; if(L <= 3) { printf("%lld\n", Ans[L]); continue; } init();//构造矩阵 solve(L-3); } return 0;}
我做完E后就一直和学弟打扑克,疯狂贪心,不过一直没太好的策略,一开始想的复杂了,情况太多了。期间老谭又过了F题。
HDU 6187 Destroy Walls
#include <bits/stdc++.h>using namespace std;const int maxn=100007;const int maxm=2000*1007;struct Edge{ int u,v,dist; Edge(){} Edge(int u,int v,int d):u(u),v(v),dist(d){} bool operator<(const Edge &rhs)const { return dist >rhs.dist;//按边长从大到小排序 }};struct Kruskal{ int n,m; Edge edges[maxm]; int fa[maxn]; int findset(int x){return fa[x]==-1? x:fa[x]=findset(fa[x]); } void init(int n) { this->n=n; m=0; memset(fa,-1,sizeof(fa)); } void AddEdge(int u,int v,int dist) { edges[m++]=Edge(u,v,dist); } pair<int,int> kruskal() { pair<int,int> ans; sort(edges,edges+m); for(int i=0;i<m;i++) { int u=edges[i].u, v=edges[i].v; if(findset(u) != findset(v)) { fa[findset(u)] = findset(v); ans.first++; ans.second+=edges[i].dist; } } return ans; }}KK;int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF){ int u,v,w; int sum=0; KK.init(n); for(int i=1;i<=n;i++) scanf("%d %d",&u,&v); for(int i=1;i<=m;i++) scanf("%d %d %d",&u,&v,&w), KK.AddEdge(u,v,w), sum+=w; pair<int,int>ans = KK.kruskal(); printf("%d %d\n",m-ans.first,sum-ans.second); } return 0;}
G我们终于有了个比较简单的思路,当前牌i先全组对子,要是没剩的就继续下一张,要是剩一张就判断i+1的个数是不是奇数,要是是奇数就判断i+2有没有,有就组个顺子。正确性:假如i+1是偶数,那么不要拆对子,无论i+2奇偶都不会变坏;i+1奇数,就可以拿出多与的一张,这样即使i+2是偶数,也就是吧一个对子(i+2的)换成了顺子,也不会变坏。
HDU 6188 Duizi and Shunzi
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<map>#include<string>using namespace std;const int MAXN=100007;int cd[MAXN];int main(){ int n; while(scanf("%d", &n)==1) { int sum=0; memset(cd, 0, sizeof(cd)); for(int i=1;i<=n;i++) { int tmp;scanf("%d", &tmp); cd[tmp]++; } for(int i=1;i<MAXN-5;i++) { sum+=(cd[i]/2); cd[i]%=2; if(cd[i]>=1&&cd[i+1]%2==1&&cd[i+2]>=1) { sum++; cd[i]--; cd[i+1]--; cd[i+2]--; } } printf("%d\n", sum); } return 0;}
这时已经过去2小时,可做题还有JBC(H?)。BJ是数据结构,C是个搜索计数,H不知道是什么。
我和学弟讨论一下J,异或可以用字典树处理,他觉得是可持久化字典树,不过不知道怎么写,我就打算写启发式合并。正打算写(感觉也写不出来),旁边队蓝名巨佬告诉我他打广西的网络同步赛用dsu过的,我瞬间兴奋,苦学一周的dsu不能浪费啊。直接上dsu+字典树。
这里说一嘴,dsu的复杂度和编码难度都比较不错,不过一般需要一种辅助数据结构去配合,就是看能不能想到这种辅助结构。解决树上无修改问题基本都能用。
HDU 6191 Query on A Tree
第一发T是因为没清vector,第二发re是因为字典树的节点个数n没清零。。。
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<map>#include<string>#define M(a,b) memset(a,b,sizeof(a))using namespace std;const int MAXN=100007;vector<int> G[MAXN];int val[MAXN];struct Query{ int id; int v; int ne;}q[MAXN];int qhead[MAXN];int qnum=0;int res[MAXN];const int bit=30;struct Trie{ int s; int ch[2]; Trie() { s=ch[0]=ch[1]=0; }}trie[MAXN*bit];int sz=1;void build() { M(trie, 0);sz=1; }void insert(int rt, int lev, int num){ if(lev==-1) { trie[rt].s=1;return; } int k=(num&(1<<lev))>>lev; if(!trie[rt].ch[k]) trie[rt].ch[k]=++sz; insert(trie[rt].ch[k], lev-1, num); trie[rt].s=trie[trie[rt].ch[0]].s|trie[trie[rt].ch[1]].s;}void remove(int rt, int lev, int num){ if(lev==-1) { trie[rt].s=0;return; } int k=(num&(1<<lev))>>lev; remove(trie[rt].ch[k], lev-1, num); trie[rt].s=trie[trie[rt].ch[0]].s|trie[trie[rt].ch[1]].s;}int query(int rt, int lev, int val){ if(lev==-1) return 0; if((val&(1<<lev))>0) { if(trie[trie[rt].ch[0]].s==1) { return query(trie[rt].ch[0], lev-1, val); } else { return query(trie[rt].ch[1], lev-1, val)+(1<<lev); } } else { if(trie[trie[rt].ch[1]].s==1) { return query(trie[rt].ch[1], lev-1, val)+(1<<lev); } else { return query(trie[rt].ch[0], lev-1, val); } }}int hson[MAXN], sonsz[MAXN];void dfs1(int u, int fa){ sonsz[u]=1; for(int i=0;i<G[u].size();i++) { if(G[u][i]!=fa) { dfs1(G[u][i], u); if(hson[u]==-1) { hson[u]=G[u][i]; } else if(sonsz[hson[u]]<sonsz[G[u][i]]) { hson[u]=G[u][i]; } sonsz[u]+=sonsz[G[u][i]]; } }}int hs;void add(int x){ insert(1, bit, val[x]); for(int i=0;i<G[x].size();i++) if(G[x][i]!=hs) add(G[x][i]);}void del(int x){ remove(1, bit, val[x]); for(int i=0;i<G[x].size();i++) if(G[x][i]!=hs) del(G[x][i]);}void dfs2(int u, int fa, int kp){ for(int i=0;i<G[u].size();i++) if(G[u][i]!=hson[u]) { dfs2(G[u][i], u, 0); } if(hson[u]) dfs2(hson[u], u, 1), hs=hson[u]; add(u);hs=0; for(int i=qhead[u];~i;i=q[i].ne) { res[q[i].id]=query(1, bit, q[i].v); res[q[i].id]^=q[i].v; } if(!kp) del(u);}int main(){ int n, qq; while(scanf("%d%d", &n, &qq)==2) { for(int i=1;i<=n;i++)G[i].clear(); for(int i=1;i<=n;i++) { scanf("%d", &val[i]); } for(int i=2;i<=n;i++) { int k;scanf("%d", &k); G[k].push_back(i); } memset(qhead, -1, sizeof(qhead)); qnum=0; for(int i=1;i<=qq;i++) { int x, v; scanf("%d%d", &x, &v); q[++qnum].v=v; q[qnum].ne=qhead[x]; qhead[x]=qnum; q[qnum].id=i; } M(hson, 0); build(); dfs1(1, 0); dfs2(1, 0, 0); for(int i=1;i<=qq;i++) { printf("%d\n", res[i]); } } return 0;}
我写J时学弟在搞数星星,不过赛后才搞出来。我写过J后就搞B的数据结构,二维的。不过处理一下可以变成一维的。先是C的代码:
HDU 6184 Counting Stars
#include<bits\stdc++.h>using namespace std;vector<int>G[100005];set<long long>s;int n, m, cnt, fa[100005];bool vis[100005];long long ans;long long getint(){ long long ret=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while('0'<=ch&&ch<='9') { ret=ret*10+ch-'0';ch=getchar(); } return ret;}int main(){ while(~scanf("%d%d", &n, &m)) { memset(vis, 0, sizeof(vis)); memset(fa, 0, sizeof(fa)); s.clear(); for(int i=1;i<=n;i++)G[i].clear(); for(int i=1;i<=m;i++) { long long x=getint(); long long y=getint(); G[x].push_back(y); s.insert((long long)n*x+y); s.insert((long long)n*y+x); G[y].push_back(x); } long long ans=0; for(int i=1;i<=n;i++) { vis[i]=1; int x=i; for(int j=0;j<G[x].size();j++)fa[G[x][j]]=x; for(int j=0;j<G[x].size();j++) { int y=G[x][j]; if(vis[y])continue; long long sum=0; if(G[y].size()<=(int)sqrt(m)) { for(int k=0;k<G[y].size();k++) { int z=G[y][k]; if(fa[z]==x)sum++; } } else { for(int k=0;k<G[x].size();k++) { int z=G[x][k]; if(s.find((long long)z*n+y)!=s.end())sum++; } } ans+=(sum-1)*sum/2; } } printf("%lld\n", ans); } return 0;}
- 2017广西邀请赛补题
- 2017广西邀请赛/hdu
- 广西 2017 邀请赛 CS Course
- 2017年广西邀请赛总结
- 2017ACM/ICPC广西邀请赛
- [广西邀请赛
- 广西2017邀请赛 Problem E CS Course
- 广西 2017 邀请赛 Duizi and Shunzi
- HDU 6186 && 2017广西邀请赛:CS Course
- 2017ACM/ICPC广西邀请赛-重现赛
- 2017ACM/ICPC广西邀请赛总结
- 2017ACM-ICPC全国邀请赛(广西)
- 2017ACM/ICPC广西邀请赛-重现赛
- 广西2017邀请赛 E: CS Course &,|,^ 运算
- 【2017广西邀请赛】hdu 6186 CS Course
- 2017ACM/ICPC广西邀请赛-重现赛
- 2017广西邀请赛 D题Covering (递推+矩阵快速幂)
- hdu6191(广西邀请赛K)
- POJ-3617Best Cow Line(贪心)(白书2.2.3)
- 分割字符串
- 遗传算法——小白
- 神经机器翻译(NMT)详细资料整理
- Oracle物化视图原理实例解析
- 2017广西邀请赛补题
- srs之与nginx-rtmp性能对比
- var、let、const 区别?
- session, sessionID和cookie
- html之vertical-align,a标签、解决塌陷通用写法
- Linux中init的命令
- 青蛙的约会(扩展欧几里得算法+不定方程求解)
- luan
- HDU 5532 Almost Sorted Array(最长不下降子序列nlogn模板)