CF830B:Cards Sorting

对叠放着的n张牌,第i张牌写有数字Ai,进行操作:将牌堆顶的牌取出,若是当前牌堆最小值就扔掉,否则放到牌堆底,求牌堆空时操作次数。

怎么看怎么像约瑟夫。。不过约瑟夫DP我不太熟,于是就yy了一下

“当前最小值”??优先队列。把Ai和i绑起来扔到优先队列里,就可以知道下一步要跳到哪里。

有个问题:如果有多个Ai怎么办???把这些相同的数字列出来,下标升序排列,假如上一次抽完牌的位置是now,那么它在把所有这些相同的数字取完后,会走到“离now最近的第一个比now小的下标”那里

因此优先队列中以数字大小为第一关键字而位置为第二,每次取出相同数字的所有位置,利用单调性边取边直接判断我们要找的“离now最近的第一个比now小的下标”(然而代码中我傻了,拿下标出来二分查找)

这样统计答案还有个小问题:有些牌已经被抽掉了,所以用下标统计答案是不行滴!那就加个树状数组吧,复杂度O(nlog2n)

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<queue>
 7 //#include<iostream>
 8 using namespace std;
 9
10 struct heapnode
11 {
12     int v,id;
13     bool operator < (const heapnode &b) const
14     {return v<b.v || (v==b.v && id<b.id);}
15     bool operator > (const heapnode &b) const {return b<*this;}
16 };
17 priority_queue<heapnode,vector<heapnode>,greater<heapnode> > q;
18 int n;
19 int x;
20 #define maxn 100011
21 int list[maxn],len;
22 #define LL long long
23 int find(int x)
24 {
25     if (x<=list[1]) return 0;
26     int L=1,R=len;
27     while (L<R)
28     {
29         int mid=(L+R+1)>>1;
30         if (list[mid]>=x) R=mid-1;
31         else L=mid;
32     }
33     return L;
34 }
35 struct BIT
36 {
37     int a[maxn];
38     int lowbit(int x) {return x&-x;}
39     int query(int x)
40     {
41         x++;
42         int ans=0;
43         for (;x;x-=lowbit(x)) ans+=a[x];
44         return ans;
45     }
46     void add(int x,int v)
47     {
48         x++;
49         for (;x<=n;x+=lowbit(x)) a[x]+=v;
50     }
51 }t;
52 int main()
53 {
54     scanf("%d",&n);
55     for (int i=0;i<n;i++)
56     {
57         scanf("%d",&x);
58         q.push((heapnode){x,i});
59         t.add(i,1);
60     }
61     int now=0;LL ans=1;
62     while (!q.empty())
63     {
64         int p=q.top().v;
65         list[len=1]=q.top().id;
66         q.pop();
67         while (!q.empty() && q.top().v==p)
68         {
69             list[++len]=q.top().id;
70             q.pop();
71         }
72         int tmp=find(now);
73         if (!tmp)
74         {
75             ans=ans+t.query(list[len])-t.query(now);
76             now=list[len];
77         }
78         else
79         {
80             ans=ans+t.query(list[tmp])+t.query(n-1)-t.query(now);
81             now=list[tmp];
82         }
83         for (int i=1;i<=len;i++) t.add(list[i],-1);
84     }
85     printf("%I64d\n",ans);
86     return 0;
87 }

时间: 2024-11-07 00:05:02

CF830B:Cards Sorting的相关文章

cf 830B - Cards Sorting 树状数组

B. Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this integer is between 1 and 10

AC日记——Cards Sorting codeforces 830B

Cards Sorting 思路: 线段树: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 100005 #define INF 0x3f3f3f3f #define maxtree maxn<<2 int n,ai[maxn],val[maxtree],L[ma

Codeforces Round #424 (Div. 2) E. Cards Sorting(线段树)

题目链接:Codeforces Round #424 (Div. 2) E. Cards Sorting 题意: 将n个数放进一个队列,每次检查队首,看看是不是队列中最小的数,如果是就扔掉,如果不是就放到队尾. 这样直到队列为空,为需要操作多少次. 题解: 考虑用两个指针模拟,最开始now指针指向第一个数,然后nxt指针指向下一个将要被删除的数. 然后我们要算出这里需要移动多少步,然后删掉这个数,一直重复操作,直到将全部的数删完. nxt指针可以用set来维护,now指针可以用并查集来维护. 计

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Cards Sorting(树状数组)

Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this integer is between 1 and 100?0

POJ_1007:DNA Sorting解题报告

[大致题意]排列多个DNA序列,按照每个序列的"有序程度".如果一个序列已经按照字母顺序排好了,那么这个序列有序程度最高,如AACCGGTT.反之,如果一个序列越无序,那么它的有序程度越低,如TGTCAA. [解题思路]计算每个序列的"逆序数",即反序字母对的个数,如ATGC的逆序数是3,因为TG,TC,GC都是逆序的.然后按照每个序列的逆序数排序,逆序数越大说明这个序列越无序. #include <iostream> #include <algo

九度oj 题目1041:Simple Sorting

题目描述: You are given an unsorted array of integer numbers. Your task is to sort this array and kill possible duplicated elements occurring in it. 输入: For each case, the first line of the input contains an integer number N representing the quantity of

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)E. Cards Sorting

题意:有n个数字,我遍历过去,如果他是当前最小值,就删除,否则放到最后面去,问得遍历多少个数字,(直到所有数字消失 思路:我们保存每个数字的位置,这个数字是否能删除,如果他在上一个数字的最后一个位置后面就可以删除了,那么标记下+树状数组(我这里的y表示的就是上一个数删除的最后一个位置) 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e5+10; 5 6 int a[

北大OJ_1007题:DNA Sorting

该题的意思是输入指定数量的字符串,每个字符串的长度一样,找出每个字符串中逆序对,然后按逆序对的升序输出所以的字符串,逆序对相同的则按输入时的顺序输出. 此题的突破点在找逆序对,以下列举两种找出逆序对的方法. 穷举法找逆序对(时间复杂度为O(n^2)) #include <iostream> #include <string> #include <deque> #include <cmath> using namespace std; struct tagSt

每日一九度之 题目1041:Simple Sorting

时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4883 解决:1860 题目描述: You are given an unsorted array of integer numbers. Your task is to sort this array and kill possible duplicated elements occurring in it. 输入: For each case, the first line of the input contains an inte