Codeforces 631C Report【其他】
2016-03-12 10:29
441 查看
题意:
给定序列,将前a个数进行逆序或正序排列,多次操作后,求最终得到的序列。分析:
仔细分析可以想到j<i,且rj小于ri的操作是没有意义的,对于每个i把类似j的操作删去(这里可以用multiset或者直接模拟栈的操作),最后我们会获得一个严格下降的序列即ri>rj && i<j,并且相邻的t不相等。那么对于ri,ri+1,对[0,ri)进行排序后,又对其子序列[0,ri+1)进行相反的排序,其实只有区间[ri+1,ri−1]]内的数是按照ti规定的排序的,并且不会再改变。所以我们只需要根据ti获取[ri+1,ri−1]]之间的值即可。
那么如何获取呢?在头尾两头设两个指针,如果对应区间要求升序,则用大的数填,否则用小的数填上。
代码:
用multiset做(做题太少第一次用set的erase)#include <cstdio> #include<set> #include<algorithm> #include<iostream> using namespace std; const int maxn = 200005; int a[maxn], b[maxn]; typedef pair<int, int>p; #define fi first #define se second multiset<p>ms; int main (void) { int n, m;scanf("%d%d", &n, &m); for(int i = 0; i < n; i++){ scanf("%d", &a[i]); b[i] = a[i]; } int maxr = 0; int r, t; multiset<p>::iterator pos; multiset<p>::iterator rp; for(int i = 0; i < m; i++){ scanf("%d%d", &t, &r); p tp = p(r, t); maxr = max(maxr, r); rp = ms.begin(); while(rp ->first <= tp.first && rp!=ms.end()) ms.erase(rp++); ms.insert(tp); } sort(b, b + maxr); int u = maxr - 1, l = 0; pos = ms.end(); pos--; int cnt = 0; while(cnt < ms.size()){ int tmp = pos->se; cnt++; if(cnt == ms.size()){ for(int j = (pos->fi) - 1; j >=0; j--){ if(tmp == 1) a[j] = b[u--]; else a[j] = b[l++]; } } else{ rp = pos--; for(int j = (rp->fi) - 1; j >= pos->fi; j--){ if(tmp == 1) a[j] = b[u--]; else a[j] = b[l++]; } } } for(int i = 0; i < n; i++){ printf("%d%c", a[i], i == n - 1?'\n':' ' ); } return 0; }
模拟栈的操作
#include <cstdio> #include<algorithm> using namespace std;//区间递减且t交叉 const int maxn = 200005; int a[maxn], b[maxn], t[maxn], r[maxn]; int main (void) { int n, m;scanf("%d%d", &n, &m); for(int i = 0; i < n; i++){ scanf("%d", &a[i]); b[i] = a[i]; } int s = 0; for(int i = 0; i < m; i++){ scanf("%d%d", &t[i], &r[i]); while(s > 0 && r[i] >= r[s - 1]){ s--; } t[s] = t[i], r[s] = r[i]; s++; } sort(b, b + r[0]); int l = r[0] - 1, u = 0; r[s] = 0; for(int i = 1; i < s + 1; i++){ for(int j = r[i - 1] - 1; j >= r[i]; j--){ if(t[i - 1] == 2) a[j] = b[u++]; else a[j] = b[l--]; } } //for(int i = 0; i < n; i++) printf("%d",b[i]); for(int i = 0; i < n; i++) printf("%d%c", a[i], i==n-1?'\n':' '); return 0; }
智商捉急。。。。比赛的时候就是想不到怎么保存有意义的操作, 就断定这题是一定是要用到自己没学过的数据结构。。真的要对自己自信呀~~思考思考!!
相关文章推荐
- Codeforces 631C Report【其他】
- mysql互换表中两列数据方法
- Win7旗舰版的nfs服务器如何架设? - Microsoft Community
- springmvc上传List,
- wex5添加视频播放
- C语言中动态申请连续的二维数组
- 安卓虚拟机启动后报错: 类似 SDK Manager] Error: Error parsing .....devices.xml 解决方案
- hdu4121 Xiangqi && uva1589 Xiangqi (模拟)
- yum 出错,提示Segmentation Fault (core Dumped) 的解决办法
- 归并排序 C++实现
- app生命周期
- 库函数计算三角形面积
- channelartlist增加limit属性
- UVa 1363 约瑟夫的数论问题
- 原生javascript的ajax
- android: PendingIntent的使用
- memcached的启动和停止
- viewcontroller生命周期
- leetcode 6. ZigZag Conversion
- NameValuePair在API22过时问题