Codeforces Round #344 (Div. 2) 乱搞+单调栈+kmp
来源:互联网 发布:宏观数据库 编辑:程序博客网 时间:2024/05/16 04:53
先写一下总结
突然有兴致去打CF…以前好像就打过一次,那次还没认真打…
英语能力有待提升,16分钟敲完前两题你猜我时间花在哪了?
明明C题离正解只有一步之遥了,但就是没想到可以划分出各个区间…智商捉急啊QAQ
D题的kmp明明考场上就get正解了,最后竟然败在了变量名和longlong上!为什么对拍没拍出错!以后还是先静态查错吧QAQ
E题只能说看懂题了,不太会搞的样子…
总之以后需要:积累考试经验,找到考试感觉,打完代码先用脑子检查一遍,思维题要大胆去想(cai)。CF只有俩小时确实时间也不太够…
虽然没我想象的那么好,不过好歹说是涨rating了,就这样吧。
A题
SB题
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int SZ = 1000010;int a[SZ],b[SZ];int main(){ int n; scanf("%d",&n); int ans1 = 0,ans2 = 0; for(int i = 1;i <= n;i ++) { scanf("%d",&a[i]); ans1 |= a[i]; } for(int i = 1;i <= n;i ++) { scanf("%d",&b[i]); ans2 |= b[i]; } printf("%d\n",ans1 + ans2); return 0;}
B题
SB题
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int SZ = 1000010;struct haha{ int id,x;}r[SZ],c[SZ];int main(){ int n,m,k; scanf("%d%d%d",&n,&m,&k); for(int i = 1;i <= k;i ++) { int k,x,a; scanf("%d%d%d",&k,&x,&a); if(k == 1) r[x] = (haha){i,a}; else c[x] = (haha){i,a}; } for(int i = 1;i <= n;i ++) { for(int j = 1;j <= m;j ++) { if(r[i].id == 0 && c[j].id == 0) printf("0 "); else if(r[i].id > c[j].id) printf("%d ",r[i].x); else printf("%d ",c[j].x); } puts(""); } return 0;}
C题
给一个序列,m次操作,每次形如:把[1,ri]按升序/降序排列。求最终序列。
容易发现,若存在一个
然后把新的操作放到一个操作序列里,满足
然后对于每个区间
这样就明确了:先处理出来新的操作序列,然后对于每两个操作序列之间的区间,依次放入最大值、次大值…或依次放入最小值、次小值…,可以通过对原数组排序后得到,具体看代码
挺好的一个乱搞题
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int SZ = 1000010;struct haha{ int r,opt;}S[SZ];int top = 0;bool cmp1(int a,int b) { return a < b; }bool cmp2(int a,int b) { return a > b; }int num[SZ],tmp[SZ];int main(){ int n,m; scanf("%d%d",&n,&m); for(int i = 1;i <= n;i ++) scanf("%d",&num[i]),tmp[i] = num[i]; for(int i = 1;i <= m;i ++) { int opt,r; scanf("%d%d",&opt,&r); while(top && r >= S[top].r) top --; S[++ top] = (haha){r,opt}; } sort(tmp + 1,tmp + S[1].r + 1,cmp1); S[top + 1].r = 0; int ll = 0,rr = S[1].r + 1;// puts(""); for(int i = 1;i <= top;i ++) { int r = S[i].r,opt = S[i].opt,r1 = S[i + 1].r + 1; // cout<<r1<<" "<<r<<" "<<opt<<endl; for(int j = r;j >= r1;j --) if(opt == 1) num[j] = tmp[-- rr]; else num[j] = tmp[++ ll]; //for(int i = 1;i <= n;i ++) printf("%d ",num[i]); puts(""); } for(int i = 1;i <= n;i ++) printf("%d ",num[i]); return 0;}/*5 55 4 3 2 11 52 41 32 21 1*/
D题
求B串在A串中出现多少次,其中字符串是这样给定的:n/m组
SBkmp,打错变量名和没开longlong毁一生QAQ
先把输入中相邻两个字母相同的合并。
然后,若B串在A串中出现,当且仅当B[1,m-2]和A[i,j]完全匹配(字母和数字完全一样);B[0]的字母和A[i-1]一样,B[0]的数字小于等于A[i-1]的数字;B[m-1]的字母和A[j+1]一样,B[m-1]的数字小于等于A[j+1]的数字。
说白了就是B串去掉头和尾然后做kmp,统计答案的时候特判一下头和尾是否合法就行了。对于m=1和m=2的情况单独处理。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int SZ = 1000010;struct haha{ LL d; char c;}aa[SZ],bb[SZ],a[SZ],b[SZ],tmp[SZ];bool operator != (haha a,haha b){ return a.d != b.d || a.c != b.c;}bool operator == (haha a,haha b){ return a.d == b.d && a.c == b.c;}int n,m;int nxt[SZ];void getnxt(haha a[],int n){ nxt[0] = nxt[1] = 0; for(int i = 1;i < n;i ++) { int j = nxt[i]; while(j && a[i] != a[j]) j = nxt[j]; nxt[i + 1] = a[i] == a[j] ? j + 1 : 0; }}LL kmp(haha a[],haha b[],haha c[]){ getnxt(a,m - 2); LL ans = 0,len = m - 2; for(int i = 0,j = 0;i < n;i ++) { while(j && b[i] != a[j]) j = nxt[j]; if(b[i] == a[j]) j ++; if(j == len) {// printf("%d %d\n",i,j);// printf("%c %c %c %c\n",c[0].c,b[i - len].c,c[m - 1].c,b[i + 1].c); if(j - len >= 0) { if(c[0].c == b[i - len].c && c[m - 1].c == b[i + 1].c) if(c[0].d <= b[i - len].d && c[m - 1].d <= b[i + 1].d) ans ++; } } } return ans;}void change(haha a[],haha aa[],int &n,int n1){ for(int i = 0;i < n1;i ++) { a[n] = aa[i]; while(i < n1 - 1 && a[n].c == aa[i + 1].c) { a[n].d += aa[i + 1].d; i ++; } n ++; }}int main(){// freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int n1,m1; scanf("%d%d",&n1,&m1); for(int i = 0;i < n1;i ++) scanf("%I64d-%c",&aa[i].d,&aa[i].c); for(int i = 0;i < m1;i ++) scanf("%I64d-%c",&bb[i].d,&bb[i].c); change(a,aa,n,n1); change(b,bb,m,m1);/* for(int i = 0;i < n;i ++) printf("%d-%c ",a[i].d,a[i].c); puts(""); for(int i = 0;i < m;i ++) printf("%d-%c ",b[i].d,b[i].c); puts("");*/ if(m == 1) { LL ans = 0; for(int i = 0;i < n;i ++) { if(a[i].c == b[0].c && a[i].d >= b[0].d) { ans += a[i].d - b[0].d + 1; // printf("%d %d\n",a[i].d,b[0].d); } } printf("%I64d",ans); } else if(m == 2) { LL ans = 0; for(int i = 0;i < n - 1;i ++) { if(a[i].c == b[0].c && a[i + 1].c == b[1].c) { if(a[i].d >= b[0].d && a[i + 1].d >= b[1].d) ans ++; } } printf("%I64d",ans); } else { for(int i = 1;i < m - 1;i ++) tmp[i - 1] = b[i]; printf("%I64d",kmp(tmp,a,b)); } return 0;}/*6 33-a 4-a 5-b 3-a 2-a 1-a3-a 4-a 5-b*/
E题
弃疗,丢官方题解。
(好像要凸壳什么高端的东西才不知道呢哼)
- Codeforces Round #344 (Div. 2) 乱搞+单调栈+kmp
- Codeforces Round #344 (Div. 2)-C. Report(单调栈)
- Codeforces Round #207 (Div. 2)---C. Knight Tournament(set乱搞)
- Codeforces Round #324 (Div. 2) 数论乱搞过
- Codeforces Round #256 (Div. 2) B. Suffix Structures (乱搞)
- Codeforces Round #346 (Div. 2)E. New Reform 乱搞dfs
- Codeforces Round #353 (Div. 2) 模拟+贪心+乱搞
- Codeforces Round #343 (Div. 2) C. Report (乱搞)
- Codeforces Round #362 (Div. 2) B. Barnicle(乱搞)
- Codeforces Round #377 (Div. 2) C. Sanatorium(规律乱搞)
- Codeforces Round #378 (Div. 2) D. Kostya the Sculptor(乱搞)
- Codeforces Round #376 (Div. 2)F. Video Cards(乱搞)
- Codeforces Round #432(div.2) D题 暴力乱搞
- Codeforces Round #344 (Div. 2) C 题题解 (贪心+单调栈)
- hdu 1711 && Codeforces Round #344 (Div. 2) D 【KMP】
- Codeforces Round #344 (Div. 2) D. Messenger(kmp)
- Codeforces Round #344 (Div. 2)D. Messenger【kmp】
- Codeforces Round #344 (Div. 2) D. Messenger(kmp,细节)
- PHP中字符串与多进制转换函数
- 【leetcode】【108】Convert Sorted Array to Binary Search Tree
- C#从零开始——使用VS生成dll并调用
- UIImageView和UIButton的区别
- RSA算法原理
- Codeforces Round #344 (Div. 2) 乱搞+单调栈+kmp
- UITableView头部ImageView下拉放大效果,导航栏透明渐变
- IOS View 背景颜色渐变--简单级别
- Universal-Image-Loader,android-Volley,Picasso、Fresco和Glide五大Android开源组件加载网络图片比较
- C++引用
- 技术团队负责人应该具备怎样的能力
- JavaScript获取li的数量 修改其样式 删除其中一个li
- Linux下php安装Redis扩展
- ios 干掉配置文件