多校第4場1012

2022-08-05 18:15:08 字數 1697 閱讀 4315

理解題意以後會發現時比較簡單的線段樹,理解題意以後首先應該想到一個貪心,就是再尋找最終答案的第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;

}

HDU多校Round 4

solved 3 rank 405 知道了s n m 可以o 1 的求s n 1, m ,s n 1,m ,s n,m 1 ,s n,m 1 天秀莫隊 include include include using namespace std typedef long long ll const ll ...

多校聯合(4)

感覺這次數學題挺多的,這次的資料應該不能說水了,有的卡的確實挺厲害,但覺得有的題還是很無語,比如說那個trouble,二分感覺不超的,就是過不了,不是wa,就是tle,還會mle,一個簡單的hash就可以過。是不是太卡演算法了。 題目 這道題真沒什麼好說的 view code 1 include 2 ...

HDU多校G4

補到兩道十分有印象的題目。 這題做法很巧妙。 題目大意 給定a b兩個陣列,分別有n和m組的 wi vi 。要求從兩個陣列中分別選出一個子陣列,使得兩個子陣列的wi和相同,並使總的vi之和最大。 首先一看是有關於價值和容量,可以想到用揹包解題。但是兩個揹包建起來複雜度會到達o 1000 1000 n...