本文主要是介绍2019 杭电多校(第五场),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1002 three arrays
http://acm.hdu.edu.cn/showproblem.php?pid=6625
题意
给你两个数组 让你排序 使他们的对应异或值字典序最小
思路
https://www.bilibili.com/video/av62396512?from=search&seid=2029202226881211707
代码
(调自闭了 请队友帮的忙(01字典树多跑了一位 初始化函数没有调用))
#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int maxn = 1e5+100;
int a[maxn],b[maxn];
int tree[50*maxn][2],tree2[50*maxn][2];
int num[50*maxn],num2[50*maxn];
int tot,tot2,top;
int n;
int ans[maxn];
int qw[40];
void init()
{tot = tot2 = 1;top = 0;tree[0][0] = tree[0][1] = tree2[0][1] = tree2[0][0] = 0;
}
void add(int x)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;if(tree[u][v] == 0){tree[tot][0] = tree[tot][1] = 0;num[tot] = 0;tree[u][v] = tot++;}u = tree[u][v];num[u]++;}
}
void add2(int x)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;if(tree2[u][v] == 0){tree2[tot2][0] = tree2[tot2][1] = 0;num2[tot2] = 0;tree2[u][v] = tot2++;}u = tree2[u][v];num2[u]++;}
}void dfs(int x1,int x2,int len,int res,int sum)
{if(len == 31){for(int i = 1;i <= sum;i++){ans[++top] = res;}return ;}int l = num[tree[x1][0]],r = num[tree[x1][1]];int ll = num2[tree2[x2][0]],rr = num2[tree2[x2][1]];if(l>0&&ll>0){int mi = min(l,ll);mi = min(mi,sum);l -= mi,ll -= mi;dfs(tree[x1][0],tree2[x2][0],len+1,res,mi);num[tree[x1][0]] -= mi,num2[tree2[x2][0]] -= mi;}if(r>0&&rr>0){int mi = min(r,rr);mi = min(mi,sum);r -= mi,rr -= mi;dfs(tree[x1][1],tree2[x2][1],len+1,res,mi);num[tree[x1][1]] -= mi,num2[tree2[x2][1]] -= mi;}if(l>0&&rr>0){int mi = min(l,rr);mi = min(mi,sum);l -= mi,rr -= mi;dfs(tree[x1][0],tree2[x2][1],len+1,res^qw[29-len+1],mi);num[tree[x1][0]] -= mi,num2[tree2[x2][1]] -= mi;}if(r>0&&ll>0){int mi = min(r,ll);mi = min(mi,sum);r -= mi,ll -= mi;dfs(tree[x1][1],tree2[x2][0],len+1,res^qw[29-len+1],mi);num[tree[x1][1]] -= mi,num2[tree2[x2][0]] -= mi;}
}
int main()
{int T;scanf("%d",&T);qw[0] = 1;for(int i = 1;i <= 30;i++){qw[i] = qw[i-1]*2;}while(T--){init();int n;scanf("%d",&n);for(int i = 1;i <= n;i++){scanf("%d",&a[i]);add(a[i]);}for(int i = 1;i <= n;i++){scanf("%d",&b[i]);add2(b[i]);}dfs(0,0,1,0,n);sort(ans+1,ans+1+n);for(int i = 1;i <= n;i++){if(i != 1) printf(" ");printf("%d",ans[i]);}printf("\n");}return 0;
}
做法二
#include <bits/stdc++.h>using namespace std;
const int maxn = 1e5+100;
int tree[maxn*40][2],tree2[maxn*40][2];
int num[maxn*40],num2[maxn*40];
int val[maxn*40],val2[maxn*40];
int tot,tot2,top;
int a[maxn],b[maxn];
map<int,int> mp;
int n;
int ans[maxn];
void init()
{tot = tot2 = 1;top = 0;tree[0][0] = tree[0][1] = tree2[0][0] = tree2[0][1] = 0;mp.clear();
}
void add(int x)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;if(tree[u][v] == 0){tree[tot][0] = tree[tot][1] = 0;num[tot] = 0;tree[u][v] = tot++;}u = tree[u][v];num[u]++;}val[u] = x;
}
void add2(int x)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;if(tree2[u][v] == 0){tree2[tot2][0] = tree2[tot2][1] = 0;num2[tot2] = 0;tree2[u][v] = tot2++;}u = tree2[u][v];num2[u]++;}val2[u] = x;
}
int query(int x)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;if(num[tree[u][v]]){u = tree[u][v];}else u = tree[u][v^1];}return val[u];
}
int query2(int x)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;if(num2[tree2[u][v]]){u = tree2[u][v];}else u = tree2[u][v^1];}return val2[u];
}
int updata(int x,int y)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;u = tree[u][v];num[u]+=y;}
}
int updata2(int x,int y)
{int u = 0;for(int i = 29;i >= 0;i--){int v = (x>>i)&1;u = tree2[u][v];num2[u]+=y;}
}int main()
{ios::sync_with_stdio(false);int T;cin>>T;while(T--){init();cin>>n;for(int i = 1;i <= n;i++){cin>>a[i];add(a[i]);mp[a[i]]++;}for(int i = 1;i <= n;i++){cin>>b[i];add2(b[i]);}int p = 1;int aa,bb,cc;while(p <= n){if(mp[a[p]] == 0){p++;if(p > n) break;continue;}aa = a[p];bb = query2(aa);cc = query(bb);while(cc != aa){aa = cc;bb = query2(aa);cc = query(bb);}ans[++top] = aa^bb;updata(aa,-1);updata2(bb,-1);mp[aa]--;}sort(ans+1,ans+1+n);for(int i = 1;i <= n;i++){if(i != 1) printf(" ");printf("%d",ans[i]);}printf("\n");}return 0;
}
1004 equation (数学)
http://acm.hdu.edu.cn/showproblem.php?pid=6627
题意
给你一个方程 求解
思路
对于绝对值 不同的区间去绝对值后式子不同 即会有(n+1)个求解区间 分别求解即可
代码
#include <bits/stdc++.h>using namespace std;
const int maxn = 1e5+100;
struct node
{int a,b;double x;int id;
}qw[maxn],ans[maxn];
int a[maxn],b[maxn];
int n, c, A, B;
double l,r;
queue<node> q;
int f;bool cmp(node a,node b)
{if(a.x != b.x) return a.x < b.x;else return a.id < b.id;
}void solve()
{if(A==0&&B == c){f = 1;return ;}double ans;ans = (double)(c-B)/A;if(ans > l&&ans <= r){int as = 1;if(ans < 0) as = -1;int x = (c - B),y = A;x = abs(x),y = abs(y);int z;if(x == 0) z = y;else z = __gcd(x,y);node u;u.a = x / z * as,u.b = y / z;q.push(u);}
}
int main()
{int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&c);A = 0,B = 0;for(int i = 1;i <= n;i++){scanf("%d%d",&a[i],&b[i]);qw[i].a = a[i],qw[i].b = b[i];qw[i].id = i;qw[i].x = (double)b[i]/a[i]*(-1.0);A += -a[i],B += -b[i];}sort(qw+1,qw+1+n,cmp);f = 0;while(!q.empty()) q.pop();l = -1e18,r = -1e18;qw[n+1].x = 1e18;for(int i = 1;i <= n+1;i++){l = r,r = qw[i].x;solve();A += qw[i].a*2;B += qw[i].b*2;}if(f) printf("-1\n");else{printf("%d",q.size());while(!q.empty()){node u = q.front();q.pop();printf(" %d/%d",u.a,u.b);}printf("\n");}}return 0;
}
1005 permutation 1 (思维)
http://acm.hdu.edu.cn/showproblem.php?pid=6628
题意
给你n个数 1 到 n 问你全排列相邻差字典序第k大的是哪个
思路
k最大10000 8个数即可 n小于8位之间暴力 大于8位直接填最后8位之前 最大8位暴力
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{int a[30];} qw[1000000];
int vis[30];
int p,n,m;
int xx[30];bool cmp(node a,node b)
{for(int i = 2; i <= m; i++){if(a.a[i]-a.a[i-1]!= b.a[i] - b.a[i-1]){return a.a[i]-a.a[i-1] < b.a[i] - b.a[i-1];}}
}void dfs(int x)
{if(x == m+1){p++;for(int i = 1; i <= m; i++){qw[p].a[i] = xx[i];}return ;}for(int i = 1; i <= n; i++){if(vis[i] == 0){vis[i] = 1;xx[x] = i;dfs(x+1);vis[i] = 0;}}
}int main()
{int T;scanf("%d",&T);while(T--){int k;scanf("%d%d",&n,&k);m = n;p = 0;memset(vis,0,sizeof(vis));if(n <= 8){dfs(1);sort(qw+1,qw+1+p,cmp);for(int i = 1; i <= n; i++){if(i != 1)printf(" ");printf("%d",qw[k].a[i]);}printf("\n");}else{printf("%d",n);vis[n] =1;for(int i = 1; i <= n - 8 - 1; i++){printf(" %d",i);vis[i] = 1;xx[1] = i;}m = 9;dfs(2);sort(qw+1,qw+1+p,cmp);for(int i = 2; i <= m; i++){printf(" %d",qw[k].a[i]);}printf("\n");}}return 0;
}
1006 string matching (扩展kmp)
http://acm.hdu.edu.cn/showproblem.php?pid=6629
题意
给你一个字符串 问从第2位 每一位和字符串相等前缀多长 (比较多少次 直到完全匹配 或 失败)
思路
拓展kmp 注意完全匹配时不需要加一次失败匹配
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
typedef long long ll;
char s[N];
int nex[N],extend[N];
ll sum;
void get_next()
{int len = strlen(s);nex[0] = len;int mx = 0,id;for(int i = 1;i < len;i++){if(i < mx) nex[i] = min(mx-i,nex[i-id]);else nex[i] = 0;while(s[i+nex[i]] == s[nex[i]]) nex[i]++;if(mx < i + nex[i]){id = i;mx = i + nex[i];}sum += (ll)min(nex[i]+1,len-i);}
}int main()
{int T;scanf("%d",&T);while(T--){scanf("%s",s);sum = 0;get_next();ll n = strlen(s);printf("%lld\n",sum);}return 0;
}
1007 permutation 2
http://acm.hdu.edu.cn/showproblem.php?pid=6630
题意
给你n个数 1-n 给你其中两个做第一和最后 打其他数填到里面 有多少种填法
思路
很容易想到如果第一位不是1 要把1-x-1填成 1 ...... x-1
最后一位不是n n后面要填成 y-1......y
中间就是 dp[i] = dp[i-1] + dp[i-3]
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll dp[100005];
int main()
{int T;scanf("%d",&T);dp[1] = 1;dp[2] = 1;dp[3] = 1;for(int i = 4;i <= 100000;i++){dp[i] = dp[i-1] + dp[i-3];dp[i] %= mod;}while(T--){ll n,x,y;scanf("%lld%lld%lld",&n,&x,&y);if(x > y) swap(x,y);if(x != 1) x++;if(y != n) y--;printf("%lld\n",dp[y-x+1]);}return 0;
}
这篇关于2019 杭电多校(第五场)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!