queue queen(误)

1. POJ2259:据说很容易的队列题(事实好像也是emmm,抛开流氓一样无赖的输入输出格式),把element变index,team number变value比其正常相反的套路要好得多。

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <queue>
 9 #include <stack>
10 #include <cmath>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long ll;
15 #define MS(x) memset(x,0,sizeof(x));
16 #define inf 0x3f3f3f3f
17 
18 const int maxn = 1e6 + 10;
19 
20 int team[maxn];
21 
22 int main()
23 {
24     int t;
25     int count = 1;
26     while (scanf("%d", &t) && t != 0)
27     {
28         queue<int> q;
29         queue<int> tq[1005];
30         MS(team);
31         printf("Scenario #%d\n", count);
32         count++;
33         for (int i = 1; i <= t; i++)
34         {
35             int times;
36             scanf("%d", &times);
37             for (int j = 1; j <= times; j++)
38             {
39                 int element;
40                 scanf("%d", &element);
41                 team[element] = i;
42             }
43         }
44         char implement[200];
45         while (scanf("%s", implement) != EOF)
46         {
47             if (implement[0] == 'S')
48                 break;
49             else if (implement[0] == 'E')
50             {
51                 int numb;
52                 scanf("%d", &numb);
53                 if (tq[team[numb]].empty())
54                     q.push(team[numb]);
55                 tq[team[numb]].push(numb);
56             }
57             else if (implement[0] == 'D')
58             {
59                 if (!tq[q.front()].empty())
60                 {
61                     printf("%d\n", tq[q.front()].front());
62                     tq[q.front()].pop();
63                 }
64                 else
65                 {
66                     q.pop();
67                     if (!tq[q.front()].empty())
68                     {
69                         printf("%d\n", tq[q.front()].front());
70                         tq[q.front()].pop();
71                     }
72                 }
73             }
74         }
75         printf("\n");
76     }
77     return 0;
78 }
My queen

2. 洛谷P2827这道题是2016NOIP的题(看到一个初三学生的压力准大二阿萌感到。。。罢了罢了)

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <queue>
 9 #include <stack>
10 #include <cmath>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long ll;
15 #define MS(x) memset(x,0,sizeof(x))
16 #define inf 0x3f3f3f3f
17 const int maxn = 1e5 + 10;
18 
19 priority_queue<int> rowinsect;//我就说蚯蚓是昆虫咋地啦
20 queue<int> insect1;
21 queue<int> insect2;
22 
23 int main()
24 {
25     int n, m, q, u, v, t;
26     scanf("%d %d %d %d %d %d", &n, &m, &q, &u, &v, &t);
27     double p = (double)u / v;
28     int lenth;
29     for (int i = 1; i <= n; i++)
30     {
31         scanf("%d", &lenth);
32         rowinsect.push(lenth);
33     }
34     int deta = 0;
35     for (int j = 1; j <= m; j++)
36     {
37         int lh, rh, mark0 = -0x7fffffff, mark1 = -0x7fffffff, mark2 = -0x7fffffff;
38         int longest = -0x7fffffff;
39         if (!rowinsect.empty())
40             longest = max(longest, rowinsect.top()), mark0 = rowinsect.top();
41         if (!insect1.empty())
42             longest = max(longest, insect1.front()), mark1 = insect1.front();
43         if (!insect2.empty())
44             longest = max(longest, insect2.front()), mark2 = insect2.front();
45         if (longest == mark0)
46             rowinsect.pop();
47         else if (longest == mark1)
48             insect1.pop();
49         else
50             insect2.pop();
51         longest += deta;
52         int pl = p * longest;
53         lh = pl - q - deta;
54         rh = longest - pl - q - deta;
55         deta += q;
56         if (j >= t && j % t == 0)
57             printf("%d ", longest);
58         insect1.push(lh);
59         insect2.push(rh);
60     }
61     printf("\n");
62     for (int i = 1; !rowinsect.empty() || !insect1.empty() || !insect2.empty(); i++)
63     {
64         int mark0 = -0x7fffffff, mark1 = -0x7fffffff, mark2 = -0x7fffffff;
65         int longest = -0x7fffffff;
66         if (!rowinsect.empty())
67             longest = max(longest, rowinsect.top()), mark0 = rowinsect.top();
68         if (!insect1.empty())
69             longest = max(longest, insect1.front()), mark1 = insect1.front();
70         if (!insect2.empty())
71             longest = max(longest, insect2.front()), mark2 = insect2.front();
72         if (i >= t && i % t == 0)
73             printf("%d ", longest + deta);
74         if (longest == mark0)
75             rowinsect.pop();
76         else if (longest == mark1)
77             insect1.pop();
78         else
79             insect2.pop();
80     }
81     return 0;
82 }
My queen

这里有两个点,第一个每切一次是需要将所有元素+q,用遍历太TLE了所以我们就用了一个deta来储存q值得累积度,和我想的一样就是其他不变单独减那两条被剪的,在后面再加回来。第二点就是如果单独用一个优先队列,那么由于二叉堆的劣根性我们还是会在某些数据上TLE,所以题解是推荐再用两个数组/普通队列进行维护,理论基础(不需要优先队列自动排序的理由)是每次先剪的蚯蚓分成的两半一定比后减的两半各比例分别都要长,所以把这两个比例用两个数组/队列存起来,得到的数组/队列本身就具备了单调性,所以一次弹出将三个top()比较也不会有问题啦。

(洛谷还有其他解法到时看心情(我觉得以后有缘吧)看咯)

3. BZOJ 2457:双端队列,(但事实不需要用队列,只是解题需要通晓队列的知识从而得出规律)(最后还是顺着点拨用自己的思路杠出来了——所以和网上标准题解不同滴!)

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <queue>
 9 #include <stack>
10 #include <cmath>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long ll;
15 #define MS(x) memset(x,0,sizeof(x))
16 #define inf 0x3f3f3f3f
17 const int maxn = 2e5 + 10;
18 
19 pair<int, int> vi[maxn];//value and index
20 int mx[maxn];
21 int mi[maxn];
22 
23 bool cmp(pair<int, int>v1, pair<int, int>v2)
24 {
25     return v1.first == v2.first ? (v1.second < v2.second) : (v1.first < v2.first);
26 }
27 
28 int main()
29 {
30     int N;
31     scanf("%d", &N);
32     for (int i = 1; i <= N; i++)
33         scanf("%d", &vi[i].first), vi[i].second = i;
34     sort(vi + 1, vi + N + 1, cmp);//由此得到关于index的变化曲线,根据规律(什么规律?自己找去)得出极小值的个数就是双端队列的个数
35     int cnt = 0;
36     for (int i = 1; i <= N; i++)
37     {
38         if (i == 1 || vi[i].first != vi[i - 1].first)
39         {
40             mx[cnt] = vi[i - 1].second;//mx表示相同value时index最大的那一个
41             mi[++cnt] = vi[i].second;//mi表示value相同时index最小的那一个
42         }
43     }
44     mx[cnt] = vi[N].second;
45     int ans = 1;
46     bool decrease = true;//判断当前为递增/递减(初始为递减)
47     int now = 0x7f7f7f7f;//当前值
48     for (int i = 1; i <= cnt; i++)//tips:i<cnt
49     {
50         if (decrease)
51         {
52             if (now > mx[i])
53                 now = mi[i];
54             else
55                 now = mx[i], decrease = false;
56         }
57         else
58         {
59             if (now > mi[i])
60                 now = mi[i], decrease = true, ans++;//以再一次递减为标志ans+1
61             else
62                 now = mx[i];
63         }
64     }
65     printf("%d", ans);
66     return 0;
67 }
My queen

4. 洛谷P1440:单调队列板子题(注意struct构造time~)

Code

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <cmath>
 9 #include <queue>
10 #define inf 0X7f7f7f7f
11 #define MS_I(x) memset(x,-inf,sizeof(x))
12 #define MS(x) memset(x,0,sizeof(x))
13 #define MSI(x) memset(x,inf,sizeof(x))
14 using namespace std;
15 typedef long long ll;
16 typedef unsigned long long ull;
17 const int maxn = 1e3 + 5;
18 using namespace std;
19 struct N
20 {
21     int time, x;//time:入队时间
22 };
23 deque<N> mq;
24 queue<int> qtop;//存储单调队列每次的队头
25 int main()
26 {
27     int n, m;
28     scanf("%d %d", &n, &m);
29     N ele;
30     qtop.push(0);
31     for (int i = 1; i < n; i++)
32     {
33         scanf("%d", &ele.x);
34         ele.time = i;
35         if (!mq.empty() && mq.front().time <= i - m)//越界队头出队
36             mq.pop_front();
37         while (!mq.empty() && mq.back().x > ele.x)//队尾出队遵循单调队列
38             mq.pop_back();
39         mq.push_back(ele);
40         qtop.push(mq.front().x);
41     }
42     while (!qtop.empty())
43     {
44         printf("%d\n", qtop.front());
45         qtop.pop();
46     }
47     return 0;
48 }
单调板板+(STL双端队列)

5. 洛谷P1886:单调队列板子题+1

Code

 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <cmath>
 9 #include <queue>
10 #define inf 0X7f7f7f7f
11 #define MS_I(x) memset(x,-inf,sizeof(x))
12 #define MS(x) memset(x,0,sizeof(x))
13 #define MSI(x) memset(x,inf,sizeof(x))
14 using namespace std;
15 typedef long long ll;
16 typedef unsigned long long ull;
17 const int maxn = 1e6 + 5;
18 using namespace std;
19 
20 int tq1[maxn], tq2[maxn];//储存对应于ele的下标
21 int ele[maxn];
22 int main()
23 {
24     int n, k;
25     scanf("%d %d", &n, &k);
26     for (int i = 1; i <= n; i++)
27         scanf("%d", &ele[i]);
28     //单调递增,队头最小
29     int b1 = 1, e1 = 0;
30     for (int i = 1; i <= n; i++)
31     {
32         if (e1 >= b1 && tq1[b1] <= i - k)
33             b1++;//队头弹出
34         while (e1 >= b1 && ele[tq1[e1]] > ele[i]) e1--;//while 队尾 > ele then 队尾弹出
35         tq1[++e1] = i;//入队并储存下标
36         if (i >= k)
37             printf("%d ", ele[tq1[b1]]);
38     }
39     puts("");
40     //单调递减,队头最大
41     int b2 = 1, e2 = 0;
42     for (int i = 1; i <= n; i++)
43     {
44         if (e2 >= b2 && tq2[b2] <= i - k)
45             b2++;
46         while (e2 >= b2 && ele[tq2[e2]] < ele[i]) e2--;//while 队尾 > ele then 队尾弹出
47         tq2[++e2] = i;
48         if (i >= k)
49             printf("%d ", ele[tq2[b2]]);
50     }
51     return 0;
52 }
单调板板+(数组表示)
 1 #pragma warning (disable:4996)
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <iomanip>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <cmath>
 9 #define inf 0X7f7f7f7f
10 #define MS_I(x) memset(x,-inf,sizeof(x))
11 #define MS(x) memset(x,0,sizeof(x))
12 #define MSI(x) memset(x,inf,sizeof(x))
13 using namespace std;
14 typedef long long ll;
15 typedef unsigned long long ull;
16 const int maxn = 1e6 + 5;
17 using namespace std;
18 struct M
19 {
20     int time, x;
21 };
22 M tq1[maxn], tq2[maxn];//储存对应于ele的下标
23 int ele[maxn];
24 int main()
25 {
26     int n, k;
27     scanf("%d %d", &n, &k);
28     for (int i = 1; i <= n; i++)
29         scanf("%d", &ele[i]);
30     //单调递增,队头最小
31     M* b1 = tq1, * e1 = tq1 - 1;
32     for (int i = 1; i <= n; i++)
33     {
34         if (e1 >= b1 && (*b1).time <= i - k)
35             b1++;//队头弹出
36         while (e1 >= b1 && (*e1).x > ele[i]) e1--;//while 队尾 > ele then 队尾弹出
37         (*++e1).time = i;//入队并储存下标
38         (*e1).x = ele[i];
39         if (i >= k)
40             printf("%d ", (*b1).x);
41     }
42     puts("");
43     //单调递减,队头最大
44     M* b2 = tq2, * e2 = tq2 - 1;
45     for (int i = 1; i <= n; i++)
46     {
47         if (e2 >= b2 && (*b2).time <= i - k)
48             b2++;
49         while (e2 >= b2 && (*e2).x < ele[i]) e2--;//while 队尾 > ele then 队尾弹出
50         (*++e2).time = i;
51         (*e2).x = ele[i];
52         if (i >= k)
53             printf("%d ", (*b2).x);
54     }
55     return 0;
56 }
单调板板+(数组+struct)

6. 多重背包的单调队列优化👉传送门

 

posted @ 2019-08-25 21:07  吴下阿萌  阅读(232)  评论(0编辑  收藏  举报