好久没写过博客了,随便写一篇……
鉴于这场ABC都是水题就不贴了,就讲一下D题吧 (我才不会说后面的我懒得看了)
因为我写完这篇blog还没结束比赛,所以我刚刚跑去看了最后两题,嗯,不会
原题
题目大意
1、选一段最长并且最左的全为零的连续子串;
2、把该字串中间设为
i
i
i。
例子的话看图吧……
ps:该答案存在并唯一
题目分析
这是个模拟题,第一眼看感觉很像快排那种分治思想,所以一开始拿了个队来做,结果发现这样做做不到最左边,之前发现不会STL库太坑了,学了一下优先队列,然后就拿了刚学的优先队列试试手。
题目代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
//你信不信我明天就看不懂这程序?
using std::priority_queue;
using std::pair;
struct cmp
{
bool operator() (pair<int,int> a,pair<int,int> b)
{
if (a.second - a.first < b.second - b.first) return true;
else if (a.second - a.first == b.second - b.first)
{
if (a.first > b.first) return true;
}
return false;
}
};
priority_queue<pair<int,int>,std::vector<pair<int,int> >,cmp> q;
//pair<int,int> l[200011];
int ls,lt,now;
int ans[200011];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ls = 0,lt = 0,now = 1;
int n;
scanf("%d",&n);
// l[lt].first = 1,l[lt++].second = n;
q.push(std::make_pair(1,n));
while (!q.empty())
{
int l = q.top().first,r = q.top().second;
int mid = (l + r) >> 1;
ans[mid] = now++;
if ((r - l + 1) % 2 == 0)
{
if (mid + 1 <= r) q.push(std::make_pair(mid + 1,r));
if (l <= mid - 1) q.push(std::make_pair(l,mid - 1));
}
else
{
if (l <= mid - 1) q.push(std::make_pair(l,mid - 1));
if (mid + 1 <= r) q.push(std::make_pair(mid + 1,r));
}
q.pop();
/* int mid = (l[ls].first + l[ls].second) >> 1;
ans[mid] = now++;
if ((l[ls].second - l[ls].first + 1) % 2 == 0)
{
if (mid + 1 <= l[ls].second) l[lt].first = mid + 1,l[lt++].second = l[ls].second;
if (l[ls].first <= mid - 1) l[lt].first = l[ls].first,l[lt++].second = mid - 1;
}
else
{
if (l[ls].first <= mid - 1) l[lt].first = l[ls].first,l[lt++].second = mid - 1;
if (mid + 1 <= l[ls].second) l[lt].first = mid + 1,l[lt++].second = l[ls].second;
}
++ls;*/
}
for (int i = 1;i <= n;++i)
printf("%d ",ans[i]);
putchar(10);
}
return 0;
}
ps:STL库是真的强……
能过证明我举一反三能力还是挺强的【滚