日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

牛客挑战赛72 总结

發布時間:2023/12/31 windows 25 coder
生活随笔 收集整理的這篇文章主要介紹了 牛客挑战赛72 总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

A

題意:給定一個數組,問有多少 \(i\in [2,n-1],a[i-1]>a[i]<a[i+1]\)
做法:模擬。

B

題意:按順序將 \(n\) 個數加入集合,維護前 \(6\) 大的數。對于每個數求出它會將第幾個數踢出前 \(6\) 或者不踢出任何其他數。
做法:模擬。可以使用priority_queue實現。但是要注意priority_queue默認大根堆,取相反數即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
    int n;cin>>n;
    int ans=n;
    vector<double> A(n);
    vector<int> Ans;
    for(int i=0;i<n;i++) cin>>A[i],A[i]*=1e8;
    priority_queue<pair<int,int> > q;
    for(int i=0;i<n;i++)
    {
        q.push(make_pair(-A[i],i));
        if(q.size()>6)
        {
            if(q.top().second==i) ans--,Ans.push_back(0);
            else Ans.push_back(q.top().second+1);
            q.pop();
        }
        else Ans.push_back(0);
    }
    cout<<ans<<endl;
    for(auto x:Ans) cout<<x<<' ';
}

C

題意:給定一棵樹,帶點權。建立一個無向完全圖,邊 \((u,v)\) 的權值為 \(lca(u,v)\) 的權值。求一條哈密頓路徑,使邊權和最大。輸出這個邊權和。\(n\leq 300\)。
做法:
假設哈密頓路徑是有向的,則可以看作每個點對應著一條入邊一條出邊(除了起點終點)。
維護 \(f[x][i]\) 表示以 \(x\) 為根的子樹中有 \(i\) 個點的出邊經過根 \(x\) 時子樹的答案。
可以發現如果一條出邊向上經過 \(x\) ,那么它發源于哪個點其實是無關緊要的,這條出邊的貢獻可能是點 \(x\) 到點 \(1\) (根節點)的路徑上的某一個點的點權。
同時,\(i\) 條出邊經過根 \(x\) 也意味著子樹 \(x\) 中包含了 \(i\) 條路徑,也就是有 \(i\) 個終點, \(i\) 個起點 。
考慮轉移,將 \(x\) 的一個兒子 \(y\) 的答案合并到 \(x\) 的答案:

\[f'[x][i+j-k]=\min\{f[x][i]+f[y][j]+k\cdot val[x]\} \]

其中枚舉 \(k\) 表示將來自于 \(y\) 的出邊塞到了 \(x\) 的其他子樹中,或者是將來自于其他子樹的出邊塞到了 \(y\) 中,這二者都會對答案產生 \(val[x]\) 的貢獻。
關于 \(k\) 還有一些小細節:
1、\(k\in [0,2\min\{i,j\}]\),假如 \(i<j\) ,則 \(j\) 超出的部分在 \(i\) 中找不到可以鏈接的位置。
2、\(i+j-k>0\) ,這是為了防止回路的出現。
另外,由于更新前后的 \(f\) 不同,所以用 \(f'\) 表示用子樹 \(y\) 更新后的 \(f\)
最后用 \(f[1][1]\) 表示答案。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 1e18
const int N=305;
vector<int> son[N];
int n,a[N],f[N][N],s[N],siz[N];
void dfs(int x)
{
    siz[x]=1;
    for(int i=0;i<=n;i++) f[x][i]=-inf;
    f[x][1]=0;
    for(int y:son[x])
    {
        dfs(y);
        for(int i=0;i<=n;i++) s[i]=-inf;
        for(int i=0;i<=siz[x];i++)
            for(int j=0;j<=siz[y];j++)
                for(int k=0;k<=min(i,j)*2;k++)
                    if(i+j-k) s[i+j-k]=max(s[i+j-k],f[x][i]+f[y][j]+k*a[x]);
        siz[x]+=siz[y];
        for(int i=0;i<=n;i++) f[x][i]=s[i];
    }
}
signed main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=2;i<=n;i++)
    {
        int x;cin>>x;
        son[x].push_back(i);
    }
    dfs(1);
    cout<<f[1][1]<<endl;
}

D

題意:給定一個 \(0\sim n-1\) 的排列,\(m\) 次詢問 \(l,r,k\) ,問區間 \([l,r]\) 中第 \(k\) 小的未出現過的數。
做法:
如果不詢問區間,那么可以用權值線段樹解決。
如果詢問的區間都是前綴,那么可以用離線后用權值線段樹解決。
如果詢問任意區間,那么可以用可持久化權值線段樹解決,也就是主席樹。
權值線段樹可以求第 \(k\) 小,反一下就可以求未出現自然數第 \(k\) 小,所以只要把每次加入的數在主席樹中新加一列就可以實現區間第 \(k\) 小。

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void read(T &x)
{
	x=0;int f=0;char ch=getchar();
	while(!isdigit(ch))	f=ch=='-',ch=getchar();
	while(isdigit(ch))	x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x=f?-x:x;
}
const int N=1e6+5;
int tree[N<<5],ls[N<<5],rs[N<<5],rt[N],n,a[N],tot,TOT,m;
#define mid (l+r>>1)
void upd(int l,int r,int pre,int &k,int x,int val)
{
	if(!k)	k=++tot;
	if(l==r)	return tree[k]=val,void();
	if(mid>=x)	rs[k]=rs[pre],upd(l,mid,ls[pre],ls[k],x,val);
	else	ls[k]=ls[pre],upd(mid+1,r,rs[pre],rs[k],x,val);
    tree[k]=tree[ls[k]]+tree[rs[k]];
}
int query(int l,int r,int pre,int k,int rk)
{
    if(l==r) return l;
    if(mid-l+1-(tree[ls[k]]-tree[ls[pre]])>=rk) return query(l,mid,ls[pre],ls[k],rk);
    return query(mid+1,r,rs[pre],rs[k],rk-(mid-l+1-(tree[ls[k]]-tree[ls[pre]])));
}
int main()
{
	read(n),read(m);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        a[i]++;
        upd(1,n,rt[i-1],rt[i],a[i],1);
    }
    while(m--)
    {
        int l,r;
        long long rk;
        read(l),read(r),read(rk);
        if(rk>n-(r-l+1)) printf("%lld\n",rk+(r-l+1)-1);
        else printf("%d\n",query(1,n,rt[l-1],rt[r],rk)-1);
    }
	return 0;
}

剩下兩題有時間再補(

總結

以上是生活随笔為你收集整理的牛客挑战赛72 总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。