Mail.Ru Cup 2018 Round 2

Mail.Ru Cup 2018 Round 2


C. Lucky Days

题意:找出最长的一段连续区间,同时被\([l_a + k_at_a, r_a + k_at_a]\) , \([l_b + k_bt_b, r_b + k_bt_b]\)覆盖。

做法:设最终的答案为\([L,R]\),那么\(L\)一定是\(l_a + k_at_a,~~ l_b + k_bt_b\), \(R\)同理。根据不同条件,解不等式,然后判断是否有解即可。其中\(k_ata - k_bt_b = k* gcd(t_a,t_b)\)

#include <bits/stdc++.h>
#define VI vector<int>
#define VL vector<ll> 
#define P pair<ll,int>
#define fr first
#define sc second
#define pb push_back
#define rep(i,a,b) for(int i = a; i <= b; ++i) 
#define per(i,a,b) for(int i = a; i >= b; --i) 
#define mem(a,b) memset(a,b,sizeof(b))
typedef long long ll;
const ll inf = 1000000000000000000LL;
using namespace std;
ll ra,la,ta,rb,lb,tb,ans;
ll fd(ll x,ll g) {ll t;t = x/g, t*=g;while(t < x) t+=g;return t;
}
int main() {scanf("%lld%lld%lld",&la,&ra,&ta);scanf("%lld%lld%lld",&lb,&rb,&tb);ll g = __gcd(ta,tb);if(ra-rb <= la - lb && fd(ra-rb,g) <= la-lb ) {ans = max(ra-la+1,ans);printf("%lld\n",ans); return 0;}if(rb-ra <= lb - la && fd(rb-ra,g) <= lb-la ) {ans = max(rb-lb+1,ans);printf("%lld\n",ans); return 0;}ll mx = max(la-lb,la-rb);//cout << mx << ' '<< ra-rb << endl;if(fd(mx,g) <= (ra-lb)) {ll X = fd(mx,g);
//      cout << "ff" << endl;ans = max((ra-lb+1) - X,ans);}mx = max(lb-la,lb-ra);if(fd(mx,g) <= (rb-la)) {ll X = fd(mx,g);
//  cout << "f";ans = max((rb-la+1) - X,ans);}printf("%lld\n",ans);return 0;
}

D. Refactoring

题意:对第一组的每个串,第一次出现的串s,将它变成t,可以获得第二组串,现在给定两组串求s和t。

做法:对每个串都取确定了一些转换,先找到每个串第一个转换关系,然后尽量向两边扩展这个串,然后就可以确定一个s,再对每个第一组串跑kmp验证即可。慎用strstr()...

#include <bits/stdc++.h>
typedef long long ll;
const int N = 3003;
using namespace std;
int n, l[N], st[N], ed[N], idx, cc;
char s1[N][N], s2[N][N], str[N];
int ck0() {for(int i = 1; i <= n; ++i) if(st[i] != 0) {if(s1[i][st[i]] == s1[idx][st[idx]] && s2[i][st[i]] == s2[idx][st[idx]] ) continue;else return 0;}return 1;
}
int ck1() {for(int i = 1; i <= n; ++i) if(st[i] != 0) {if(st[i] == 1) return 0;else {if(s1[i][st[i]-1] == s1[idx][st[idx]-1] && s2[i][st[i]-1] == s2[idx][st[idx]-1] ) continue;else return 0;}}return 1;
}
int ck2() {for(int i = 1; i <= n; ++i) if(st[i] != 0) {if(ed[i] == l[i]) return 0;else {if(s1[i][ed[i]+1] == s1[idx][ed[idx]+1] && s2[i][ed[i]+1] == s2[idx][ed[idx]+1] ) continue;else return 0;}}return 1;
}int nxt[N];
void getnxt(char s[],int n){nxt[1]=0;for(int i=2;i<=n;i++){int j=nxt[i-1];while(j&&s[j+1]!=s[i]) j=nxt[j];if(s[j+1]==s[i]) nxt[i]=j+1;else nxt[i] = 0;}
}
int kmp(char p[],int m, char s[], int n){int j=0;for(int i=1;i<=n;i++){while(j&&p[j+1]!=s[i]) j=nxt[j];if(p[j+1]==s[i])++j;if(j==m) {        return i-m+1;}}return -1;
}
int main() {scanf("%d",&n);for(int i = 1; i <= n; ++i) scanf(" %s",s1[i]+1), l[i] = strlen(s1[i]+1);for(int i = 1; i <= n; ++i) scanf(" %s",s2[i]+1);for(int i = 1; i <= n; ++i) {for(int j = 1; j <= l[i]; ++j) if(s1[i][j] != s2[i][j]) {idx = i;st[i] = ed[i] = j;break;}}if(idx == 0) {puts("YES"); printf("a\na\n");return 0;}if(!ck0()) {return  puts("NO"),0;}while(ck1()) {for(int i = 1; i <= n; ++i)if(st[i]!=0) --st[i];}while(ck2()) {for(int i = 1; i <= n; ++i)if(ed[i]!=0) ++ed[i];}for(int i = st[idx]; i <= ed[idx]; ++i) str[++cc] = s1[idx][i]; str[cc+1] = '\0';getnxt(str,cc);for(int i = 1; i <= n; ++i) {int p = kmp(str,cc,s1[i],l[i]);if(st[i] != 0) {if(p != st[i]) return puts("NO"),0;}else if(p != -1) {return puts("NO"),0;}}puts("YES");printf("%s\n",str+1);for(int i = st[idx]; i <= ed[idx]; ++i) printf("%c",s2[idx][i]);puts("");return 0;
}

E. Segments on the Line

题意:给定一个长度为\(n\)的序列\(a\),以及\(s\)个区间\([l_i,r_i]\),从这些区间中,挑恰好\(m\)个区间,他们的并区间中元素第\(k\)小的值为这种方案的答案,求最小的答案。

做法:首先,二分第\(k\)小的值\(v\),然后问题就转换为求,挑\(m\)个区间他们中小于\(v\)的数最多是多少。将区间按照右端点排序,\(dp[i][j]\)表示前\(i\)个区间选了\(j\)个,且第\(i\)个一定选了的小于\(v\)的数目,转移有两种:1)第\(i\)个区间与前一个区间不相交,这个需要维护每个位置向前,用了\(j\)个区间,的\(dp\)的最大值;2)第\(i\)个区间与前一个区间不相交,这时取上一个区间取左端点尽可能小的一定更优,因为较大的左端点一定可以被他包含,对每个区间维护一下前一个不相交的区间,和相交的中左端点最小的区间。还有一种,情况有区间相互包含的情况,显然取大的更优。(我的实现有点麻烦。。懒得改了。

#include <bits/stdc++.h>
#define pb push_back
typedef long long ll;
const int N = 1600;
using namespace std;
int n,s,m,k,a[N];
vector<int> v[N];
struct node{ int l,r; } b[N];
bool cmp(node a,node b) {if(a.r != b.r) return a.r < b.r;return a.l < b.l;
}
int dp[N][N], MX[N][N], pre[N], pl[N];
int cal(int x) {int ans = 0;memset(dp,0,sizeof(dp));dp[1][1] = MX[1][1] = upper_bound(v[1].begin(),v[1].end(),x) - v[1].begin();for(int i = 1,c=0,c2=0; i <= s; ++i) {c = c2 = 0;if(pl[i] != 0) {for(int j = b[pl[i]].r+1; j <= b[i].r; ++j) c2 += (a[j] <= x);}c = upper_bound(v[i].begin(),v[i].end(),x) - v[i].begin();dp[i][1] = c;for(int j = 2; j <= i && j <= m; ++j) {if(pre[i] != 0) dp[i][j] = max(dp[i][j], MX[pre[i]][j-1] + c);if(pl[i] != 0) dp[i][j] = max(dp[i][j], dp[pl[i]][j-1] + c2);dp[i][j] = max(dp[i][j], dp[i][j-1]);}for(int j = 1; j <= i && j <= m; ++j) MX[i][j] = max(MX[i-1][j], dp[i][j]);ans = max(ans, dp[i][m]);}return ans;
}int main() {scanf("%d%d%d%d",&n,&s,&m,&k);for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);for(int i = 1; i <= s; ++i) {scanf("%d%d",&b[i].l,&b[i].r);}sort(b+1, b+1+s, cmp);for(int i = 1; i <= s; ++i) { for(int j = b[i].l ; j <= b[i].r ; ++j) v[i].pb(a[j]);sort(v[i].begin(),v[i].end());}for(int i = 1; i <= s; ++i) {int mx = 0, idx = 0, mn = 1000000, idx2 = 0;for(int j = 1; j < i; ++j) {if(b[j].r < b[i].l && mx < b[j].r) {mx = b[j].r; idx = j;}if(b[j].r >= b[i].l && mn > b[j].l) {mn = b[j].l; idx2 = j;}}pre[i] = idx; pl[i] = idx2;}int l = 1, r = 1e9, mid, ans = -1;while(l <= r) {ll mid = (l + r) >> 1;if(cal(mid) >= k) r = mid-1, ans = mid;else l = mid + 1;}printf("%d\n",ans);return 0;
}

F. Tree and XOR

题意:给定一棵\(n\)节点的树,每条边都有权值,一条从\(u\)\(v\)的路径的价值定义为路径上边权的异或和,问所有\(n^2\)个路径中,第\(k\)小的路径的异或和是多少。

做法:两点之间路径的价值,可以通过他们到根的前缀异或和相异或求得。于是,问题转化为\(n\)个数,问他们两两之间的\(n^2\)个异或值中,第\(k\)小的是什么。首先,一个思路就是,二分答案,然后枚举一个数,在\(trie\)树上查询比这个数小的数的个数。复杂度是有两个\(log\)。考虑直接通过\(trie\)树,确定答案的每一位是什么,对于每个数维护他当前所在的\(Trie\)树上的节点,计算当前层异或为\(0\)的数目\(sum\),如果\(k>sum\),那么这一位是\(1\),否则是\(0\)。然后,更新每个数,在\(Trie\)树上的位置。这样时间可以做到\(O(62logn)\),但是,空间依然不够,看了别人的代码,可以换一种实现,在建\(Trie\)树的同时,计算,每次先插入当前层的数,建好当前层,再枚举计算当前位异或为\(0\)的数目,更新每个数的位置。注意到我们每次使用的节点只有上一层的,那么就可以每次只保留最后一层的节点,新的节点可以复用之前的空间

#include <bits/stdc++.h>
typedef long long ll;
const int N = 1000100;
using namespace std;
int n;
ll k,w[N],ans;
int rt[N], prt[N], num[N], cc, ch[N][2];
int main() {scanf("%d%lld",&n,&k);for(int p,i = 2; i <= n; ++i) scanf("%d%lld",&p,&w[i]), w[i]^=w[p];for(int i = 1; i <= n; ++i) rt[i] = prt[i] = 1;for(int s = 61; s >= 0; --s) {for(int i = 1; i <= cc; ++i) ch[i][0]=ch[i][1]=num[i]=0; cc = 1;for(int i = 1; i <= n; ++i) {int t = (w[i]>>s)&1;if(!ch[rt[i]][t]) ch[rt[i]][t] = ++cc;rt[i] = ch[rt[i]][t];num[rt[i]]++;}ll sum = 0;for(int i = 1; i <= n; ++i) {int t = (w[i]>>s)&1;sum += num[ch[prt[i]][t]];}if(sum < k) {ans |= (1LL<<s);k-=sum;for(int i = 1; i <= n; ++i) {int t = (w[i]>>s)&1;prt[i] = ch[prt[i]][t^1];}}else {for(int i = 1; i <= n; ++i) {int t = (w[i]>>s)&1;prt[i] = ch[prt[i]][t];}}}printf("%lld\n",ans);return 0;
}

转载于:https://www.cnblogs.com/RRRR-wys/p/9969522.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用ML.NET实现基于RFM模型的客户价值分析

RFM模型在众多的客户价值分析模型中&#xff0c;RFM模型是被广泛应用的&#xff0c;尤其在零售和企业服务领域堪称经典的分类手段。它的核心定义从基本的交易数据中来&#xff0c;借助恰当的聚类算法&#xff0c;反映出对客户较为直观的分类指示&#xff0c;对于没有数据分析和…

【模拟】【递归】【dfs】恐怖的奴隶主

恐怖的奴隶主 题目大意&#xff1a; 有4个bigbob&#xff08;我们简称BB&#xff09;&#xff0c;每个BB有自己的初始血量&#xff08;最大为k&#xff09;&#xff0c;当某个BB死后&#xff0c;其他受伤的BB会在最左边的空格召唤一个最大血量为s[t]的BB&#xff08;t为当前受…

[2020.11.4NOIP模拟赛]简单的打击【NTT】

正题 题目链接:https://www.luogu.com.cn/problem/U138580 题目大意 两个长度为nnn的序列&#xff0c;要求重排后同位置的相加后众数的个数最多。 解题思路 定义aia_iai​为第一个序列中iii的出现次数&#xff0c;那么同理有bbb 不难对于每个众数iii的出现次数cic_ici​&…

Reordering the Cows

牛客网传送 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format:%lld 链接&#xff1a;https://ac.nowcoder.com/acm/contest/4860/B 来源&#xff1a;牛客网 题目描述 Farmer John’s N cows (…

Educational Codeforces Round 54 (Rated for Div.2)

Educational Codeforces Round 54 (Rated for Div.2) D. Edge Deletion 题意&#xff1a;一张n个点的无向图&#xff0c;保留其中k条边&#xff0c;使得有尽可能多的点与1的最短路长度不变。 做法&#xff1a;求出最短路树&#xff0c;然后自底向上删边即可。 #include <bit…

回顾4180天在腾讯使用C#的历程,开启新的征途

今天是2018年8月8日&#xff0c;已经和腾讯解除劳动关系&#xff0c;我的公司正式开始运营&#xff0c;虽然还有很多事情需要理清&#xff0c;公司官网也没有做&#xff0c;接下来什么事情都需要自己去完成了&#xff0c;需要一步一个脚印去完善&#xff0c;开启一个新的征途。…

【dfs】【拓扑排序】组合树

组合树 题目大意&#xff1a; 有一棵树&#xff0c;每个点都有自己的原颜色和目标颜色&#xff08;黑或白&#xff09;&#xff0c;现在深度不小于k的点可以让自己祖宗k代k个点的颜色全部取反&#xff0c;现在问当前树是否能变成目标树 输入样例 2 3 2 1 2 2 3 0 0 0 1 0 1…

P5906-[模板]回滚莫队不删除莫队

正题 题目链接:https://www.luogu.com.cn/problem/P5906 题目大意 nnn个数字&#xff0c;mmm个询问[l,r][l,r][l,r]中最远的相同数字对。 解题思路 我们考虑如何用莫队维护&#xff0c;对于一个询问[l,r][l,r][l,r]&#xff0c;我们先按照lll的块排再按照rrr排&#xff0c;定…

Secret Code(原题和变形题)

洛谷传送 牛客网题一 牛客网题二 没错牛客网有两个题&#xff0c;牛客网题一和洛谷是一样的题&#xff0c;牛客网题二是题一的变形 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld 链…

Codeforces Round #520 (Div. 2)

Codeforces Round #520 (Div. 2) D. Fun with Integers 题意&#xff1a;a与b之间有边&#xff0c;当且仅当存在一个\(x\)使得\(a*b x\)或 \(a*x b\)&#xff0c;这条边的边权为\(|x|\)&#xff0c;保证\(|a|,|b|,|x|<n\)&#xff0c;问一条最长的不走重复边的路径的长度是…

稳定工作和创业之间的抉择

早上写的文章《回顾4180天在腾讯使用C#的历程&#xff0c;开启新的征途》是我在腾讯写的最后一篇对过往10年在腾讯使用C#语言的总结&#xff0c;今天收到反馈有人在造谣腾讯开始去.net&#xff0c;我被迫辞职了。这非常的不负责任&#xff0c;我必须写这篇文章来辟谣。要说腾讯…

初二模拟赛总结(2019.8.7)

成绩&#xff1a; rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4111hkyhkyhky180180180100100100808080000000222lyflyflyf170170170100100100707070000000333tjhtjhtjh160160160100100100404040000202020444fyfyfy160160160606060100100100000000555cyzcy…

牛客2020年愚人节比赛

欢乐的一晚上 题目链接 其实做做也挺好&#xff0c;脑筋急转弯&#xff0c;不需要算法不需要数据结构&#xff0c;纯娱乐 还有不知道是哪位哥的&#xff0c;心疼一下 题解 注&#xff1a;一下题解没必要较劲&#xff0c;欢乐局而已 对不对无所谓&#xff0c;换了最重要奥 A题ra…

P4655-[CEOI2017]Building Bridges【斜率优化dp,CDQ分治】

正题 题目链接:https://www.luogu.com.cn/problem/P4655 题目大意 nnn座桥&#xff0c;删除第iii座会产生wiw_iwi​的代价&#xff0c;相邻的两座桥i,ji,ji,j会产生(hi−hj)2(h_i-h_j)^2(hi​−hj​)2的代价&#xff0c;要求代价最小。 解题思路 设fif_ifi​表示留到第iii座桥…

Codefroces1077F2. Pictures with Kittens (hard version)

Codefroces1077F2. Pictures with Kittens (hard version) 做法&#xff1a;裸的单调队列优化dp #include <bits/stdc.h> #define P pair<ll,ll> #define fr first #define sc second typedef long long ll; using namespace std; int n, m, x; ll dp[5002][5002],…

IdentityServer4 知多少

1. 引言现在的应用开发层出不穷&#xff0c;基于浏览器的网页应用&#xff0c;基于微信的公众号、小程序&#xff0c;基于IOS、Android的App&#xff0c;基于Windows系统的桌面应用和UWP应用等等&#xff0c;这么多种类的应用&#xff0c;就给应用的开发带来的挑战&#xff0c;…

【线段树】矮人排队(jzoj(gz) 3236)

矮人排队 jzoj &#xff08;gz&#xff09;3236 题目大意&#xff1a; 有n个人&#xff0c;高度分别为1,2……n&#xff08;高度按输入来看&#xff09;&#xff0c;现在有两种操作 1&#xff1a;把第x个人和第y个人换一下 2&#xff1a;询问高度为A&#xff0c;A1……B这B-…

牛客网【每日一题】4月2日 月月查华华的手机

牛客网链接 时间限制&#xff1a;C/C 2秒&#xff0c;其他语言4秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld 题目描述 月月和华华一起去吃饭了。期间华华有事出去了一会儿&#xff0c;没有带手机。月月出于人类最单纯的好奇心&#…

P3466-[POI2008]KLO-Building blocks【Treap】

正题 题目链接:https://www.luogu.com.cn/problem/P3466 题目大意 nnn个数&#xff0c;每次可以让一个111或−1-1−1&#xff0c;要求操作次数最少使得有连续kkk个相同的。 解题思路 枚举是哪kkk个&#xff0c;然后用平衡树&#xff08;或对顶堆&#xff09;维护中位数和比中…

Codeforces1080F. Katya and Segments Sets

Codeforces1080F. Katya and Segments Sets 题意&#xff1a;给定n个集合&#xff0c;每个集合里有一些区间\([l_i,r_i]\)&#xff0c;有m次询问&#xff0c;每次询问区间\([x,y]\)中&#xff0c;是否包含了集合a到集合b中每个集合至少一个区间。 做法&#xff1a;按区间右端点…