理解題意以後會發現時比較簡單的線段樹,理解題意以後首先應該想到乙個貪心,就是再尋找最終答案的第i個數時,餓哦們要盡量使這個數盡可能大。那麼我們找[1,pos[i]+1]這個區間中已經組隊的位置的最大值,記為l,然後找[l+1pos[i]+1]之間未被找過的最大的數。(這裡組隊的意思是可以詳見程式,並不是被找過了)。然後注意一下細節,是乙個比較好維護的線段樹,複雜付就是線段樹的複雜度o(nlogn)。
題解上寫維護組隊的右端點是用set維護的,比賽當時也想到了用set維護,但是後來感覺好像只需要把pushup和modify稍加修改就好了,但是改了一下,感覺有點煩,索性就複製,貼上,多謝了2個函式(幾乎一樣的)。
#include #include #include #include #include #define for(i,x,y) for(int i = x;i < y;i ++)
#define ifor(i,x,y) for(int i = x;i > y;i --)
#define ll long long
#define lrt rt<<1
#define rrt rt<<1|1
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define n 100010
using namespace std;
int pos[n],num[n],ans[n],n;
bool vis[n];
struct treetree[n<<2];
void pushup(int rt)
void build(int rt,int l,int r)
int mid = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}void modify(int rt,int k)
int mid = (tree[rt].l+tree[rt].r)>>1;
if(k <= mid) modify(lrt,k);
else modify(rrt,k);
pushup(rt);
}int query(int rt,int l,int r)
}int query_en(int rt,int l,int r)
}void pushup_en(int rt)
void modify_en(int rt,int k)
int mid = (tree[rt].l+tree[rt].r)>>1;
if(k <= mid) modify_en(lrt,k);
else modify_en(rrt,k);
pushup_en(rt);
}int main()
build(1,1,n);
for(i,1,n+1)
else ans[i] = tem;}}
vis[ans[i]] = true;
modify(1,pos[ans[i]]);
if(pos[ans[i]] <= pos[i])
modify_en(1,pos[i]);
if(pos[ans[i]] < pos[i])}}
printf("%d",ans[1]);
for(i,2,n+1)
printf("\n");
}return 0;
}
多校第4場1012
理解題意以後會發現時比較簡單的線段樹,理解題意以後首先應該想到乙個貪心,就是再尋找最終答案的第i個數時,餓哦們要盡量使這個數盡可能大。那麼我們找 1,pos i 1 這個區間中已經組隊的位置的最大值,記為l,然後找 l 1pos i 1 之間未被找過的最大的數。這裡組隊的意思是可以詳見程式,並不是被...
多校第9場
這道題挺水,只是要耐心的打表,我一開始只打了一半就不想做了,也是因為我的方法太麻煩了,把x,y座標分開存,處理的資料量差不多增加了一倍。這題有一點注意 題目中並沒有限制字串的長度,所以char陣列盡量開大些。下面是賽後ac的 include include include include inclu...
2016多校第10場
1001 media tag 二分 題意給你乙個排好的n個數,讓你求l1,r1,和 l2,r2這兩區間合併起來的中位數。分析 我們可以很容易將這個問題轉化為第k問題,因此我們二分這個數,假設他是第k大那麼小於等於它的數的數量肯定大於等於k。include include include using ...