字典树 模板

来源:互联网 发布:企业网络架构方案 编辑:程序博客网 时间:2024/06/05 05:47

origin : http://acm.bnu.edu.cn/v3/problem_show.php?pid=52723

from : CodeForcesGym

time limit : 6000 ms

memory limit : 1048576 KB

题意:求一串数中任意两数不进位相加的最小值和最大值

解法:对于每个数,建19位字典树,注意避免自相加即可

time used : 3213 ms

memory used : 947000 KB

Accepted :


#include <cstdio>#include <algorithm>#define constant const constexprtypedef long long ll;constant int maxN = 20e6 + 3;constant ll maxNUM = 1e6 + 3;int N,M;int number[19];ll num;ll nums[maxNUM];void reading(){std::scanf("%d",&N);for (int i=0;i<N;++i) std::scanf("%I64d",nums+i);}void readin(int t){num = nums[t];for (int i=18;i>=0;--i){ll t = num % 10LL;number[i] = static_cast<int>(t);num /= 10LL;}}// Trieint cnt;struct node{int it;int next[10];int count;node (int _it = -1):it(_it),count(0){std::fill_n(next,10,-1);}};node Trie[maxN];void init(){cnt = 0;}void add(int t){readin(t);int i = 0, now = 0;while (i < 19){int t = number[i];++Trie[now].count;if (Trie[now].next[t] == -1) Trie[now].next[t] = ++cnt;now = Trie[now].next[t];Trie[now].it = t;//std::printf("%d %d %d\n",i,t,now);++i;}++Trie[now].count;}ll query_min(){//std::printf("Min Query:\n");bool same_flag = true;num = 0;int i = 0, now = 0;while (i < 19){int t_it = number[i];int t = (10-t_it)%10;while (true){int it_cnt = Trie[now].next[t];if (it_cnt == -1) t = (t+1)%10;else if ((Trie[it_cnt].count == 1) and (same_flag) and (Trie[it_cnt].it == t_it)) t = (t+1)%10;else{if (Trie[it_cnt].it != t_it) same_flag = false;num = 10LL*num+static_cast<ll>((t+t_it)%10);now = it_cnt;break;}}//std::printf("%d %d %d %lld %d %d %d %d\n",i,t_it,t,num,same_flag,Trie[now].count,Trie[now].it,t_it);++i;}return num;}ll query_max(){//std::printf("Max Query:\n");bool same_flag = true;num = 0;int i = 0, now = 0;while (i < 19){int t_it = number[i];int t = (9-t_it)%10;while (true){int it_cnt = Trie[now].next[t];if (it_cnt == -1) t = (t+9)%10;else if ((Trie[it_cnt].count == 1) and (same_flag) and (Trie[it_cnt].it == t_it)) t = (t+9)%10;else{if (Trie[it_cnt].it != t_it) same_flag = false;num = 10LL*num+static_cast<ll>((t+t_it)%10);now = it_cnt;break;}}//std::printf("%d %d %d %lld %d %d %d %d\n",i,t_it,t,num,same_flag,Trie[now].count,Trie[now].it,t_it);++i;}return num;}int main(){init();reading();for (int i=0;i<N;++i) add(i);ll maximum = 0LL, minimum = 9223372036854775807LL, tmp;for (int i=0;i<N;++i){readin(i);tmp = query_min();if (tmp < minimum) minimum = tmp;tmp = query_max();if (tmp > maximum) maximum = tmp;}std::printf("%I64d %I64d",minimum,maximum);}


原创粉丝点击