Codeforces #831E: Cards Sorting 题解
来源:互联网 发布:知乎 碧桂园森林城市 编辑:程序博客网 时间:2024/05/22 16:44
题目里面的将第一张放到牌堆最下面看起来很玄乎,其实就是摸牌的时候循环摸牌
我们的目标是在摸完第i张牌后,迅速判断要摸到第i+1张牌要再摸几次
于是我们可以用线段树来维护一个区间内还有多少牌没有被扔出去,这样每次做一个区间查询,扔牌时做一个单点修改就好
这题还有一个难点是如何确定牌的大小次序
对于序号不同的牌,当然是序号小的靠前
对于序号相同的牌,要看上一种牌的最后一张在哪里,然后按照
1.在它后面的一定比在它前面的小
2.都在它后面的离它越近越小
3.都在它前面的离它越远越小
进行排序
注意:牌上的序号是<=1e5,不是n
#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <cstdlib>#include <utility>#include <map>#include <stack>#include <set>#include <vector>#include <queue>#include <deque>#include <bitset>#define x first#define y second#define mp make_pair#define pb push_back#define LL long long#define Pair pair<int,int>#define LOWBIT(x) x & (-x)using namespace std;const int zero_stand=1500;const int MOD=1e9+7;const int INF=0x7ffffff;const int magic=348;vector<int> v[100048];int stand;struct node{int left,right;int sum;}tree[300048];void build(int cur,int left,int right){tree[cur].left=left;tree[cur].right=right;tree[cur].sum=right-left+1;if (left!=right){int mid=(left+right)>>1;build(cur*2,left,mid);build(cur*2+1,mid+1,right);}}void update(int cur,int pos){if (tree[cur].left==tree[cur].right){tree[cur].sum=0;return;}int mid=(tree[cur].left+tree[cur].right)>>1;if (pos<=mid) update(cur*2,pos); else update(cur*2+1,pos);tree[cur].sum=tree[cur*2].sum+tree[cur*2+1].sum;}int query(int cur,int left,int right){if (left>right) return 0;if (left<=tree[cur].left && tree[cur].right<=right){return tree[cur].sum;}int mid=(tree[cur].left+tree[cur].right)>>1;int res1=0,res2=0;if (left<=mid) res1=query(cur*2,left,right);if (mid+1<=right) res2=query(cur*2+1,left,right);return res1+res2;}int n;Pair a[100048];int pos[100048];bool cmp(int x,int y){if (x-stand>0 && y-stand<0 || x-stand<0 && y-stand>0) return x-stand>y-stand;if (x-stand>0 && y-stand>0) return x-stand<y-stand;if (x-stand<0 && y-stand<0) return x-stand<y-stand;}int main (){int i,j;scanf("%d",&n);for (i=1;i<=n;i++){scanf("%d",&a[i].x);a[i].y=i;v[a[i].x].pb(i);}int t=1;while (v[t].size()==0) t++;sort(v[t].begin(),v[t].end());stand=v[t].back();t++;do{while (t<=100000 && v[t].size()==0) t++;if (t>100000) break;sort(v[t].begin(),v[t].end(),cmp);stand=v[t].back();t++;}while (t<=100000);build(1,1,n);int top=0;for (i=1;i<=100000;i++)if (v[i].size()!=0)for (j=0;j<v[i].size();j++)pos[++top]=v[i][j];pos[0]=0;LL ans=0;int cnt;for (i=1;i<=n;i++){if (pos[i-1]+1<=pos[i]){cnt=query(1,pos[i-1]+1,pos[i]);ans+=cnt;}else{cnt=query(1,pos[i-1]+1,n);cnt+=query(1,1,pos[i]);ans+=cnt;}update(1,pos[i]);}cout<<ans<<endl;return 0;}
阅读全文
1 0
- Codeforces #831E: Cards Sorting 题解
- codeforces 831 E Cards Sorting(bit+stl)
- Codeforces-831E Cards Sorting(树状数组)
- Codeforces 831-E.Cards Sorting(线段树)
- Codeforces 831 E. Cards Sorting set+树状数组模拟
- Codeforces Round #424 Div2 E. Cards Sorting
- Codeforces Round #424 E. Cards Sorting
- Codeforces Round #424 (Div. 2) E. Cards Sorting(树状数组)
- codeforces 830B. Cards Sorting
- Codeforces B. Cards Sorting 【瞎搞】
- Codeforces Round #424 (Div. 2) E. Cards Sorting(思维 树状数组)
- Codeforces Round #424 (Div. 2, )-树状数组|线段树-E. Cards Sorting
- Codeforces Round #424 E. Cards Sorting 线段树/数据结构瞎搞/模拟
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) E Cards Sorting
- Codeforces Round #424 (Div. 2)C. Jury Marks 暴力 D. Office Keys 二分 E. Cards Sorting 树状数组
- Codeforce#424E. Cards Sorting(脑洞+树状数组)
- CodeForces 387E George and Cards
- [DP]Codeforces 743E Vladik and cards
- 第一个hello world in python
- java同步和异步
- 数据结构
- 矩阵的算法
- 初识计算机
- Codeforces #831E: Cards Sorting 题解
- python文件操作
- 浅析Java基本数据类型
- 【学习笔记】 初学JS写了个轮播图
- 苹果APP开发技术支持
- ZOJ3870 Team Formation【位运算+数学】
- 坚持#第186天~好久没写了,我想变优秀,所以要坚持写
- 线程互斥和同步(二 方式)线程
- intellij 中使用gulp