1. 程式人生 > >Codeforces Round #353 (Div. 2)

Codeforces Round #353 (Div. 2)

auto ide body 復雜 uil code pop pri cos

A:水題

技術分享圖片
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define
pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using
namespace std; const double g=10.0,eps=1e-12; const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f; int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(c==0) { if(a==b)puts("YES"); else puts("NO"); return 0; } if((b-a)%c==0) {
if(a>=b&&c<=0)puts("YES"); else if(a<=b&&c>=0)puts("YES"); else puts("NO"); } else puts("NO"); return 0; } /******************** ********************/
A

B:sb公式題,把公式列出來枚舉即可

技術分享圖片
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f;


int main()
{
    ll n,a,b,c,d;
    scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&c,&d);
    ll ans=n;
    ll te1=a+b,te2=a+c,te3=b+d,te4=c+d;
    ll te=max(te1,max(te2,max(te3,te4)))-min(te1,min(te2,min(te3,te4)));
    te=max(0ll,te);te=min(n,te);
    te=n-te;
    printf("%lld\n",ans*te);
    return 0;
}
/********************

********************/
B

C:題意:給你n個數,每次能把一個數轉移到隔壁,1和n是隔壁,要求最少幾次能把每個數變成0

題解:前綴和維護一下,前綴和相同就代表這一段區間和為0,那麽就可以少轉移一次,map維護一下瞎搞就行了

技術分享圖片
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;

ll a[N],sum[N];
map<ll,ll>ma;
int main()
{
    ll n;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
        ma[sum[i]]++;
    }
    ll ans=n-1;
    for(auto x:ma)ans=min(ans,n-x.se);
    printf("%lld\n",max(0ll,ans));
    return 0;
}
/********************

********************/
C

D:題意:給你n個數,依次插入到二叉搜索樹裏,看每個點的父親節點價值是多少

題解:很明顯不能模擬,退化成一條鏈 的時候復雜度O(N^2),所以我們需要用set來維護一下,當插入值是x時,前驅是l,後繼是r,x要麽是l的右兒子,要麽是r的左兒子,,又因為l沒有右兒子和r沒有左兒子不能同時成立,所以找到另一個插入即可.set+upperbound即可

黑體字的證明:假設l沒有右兒子而且r沒有左兒子,而且l,r不能是另一個的祖先(這樣不滿足假設),那麽l,r的公共祖先為a,那麽a要麽是前驅,要麽是後繼,所以假設不成立

技術分享圖片
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;

struct point{
    int v;
    mutable bool l,r;
    bool operator <(const point &rhs)const{
        return v<rhs.v;
    }
}p[N];
set<point>s;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&p[i].v);
        p[i].l=p[i].r=0;
        if(i!=1)
        {
            auto te=s.upper_bound(p[i]);
            if(te==s.end())
            {
                te--;
                (*te).r=1;
                printf("%d ",(*te).v);
            }
            else
            {
                if((*te).l==0)
                {
                    (*te).l=1;
                    printf("%d ",(*te).v);
                }
                else
                {
                    te--;
                    (*te).r=1;
                    printf("%d ",(*te).v);
                }
            }
        }
        s.insert(p[i]);
    }
    puts("");
    return 0;
}
/********************

********************/
D

E:題意:給你n個車站,從i到i+1~a[i]只需要一步,i到j的價值是最少需要走的步數μ(i,j),求每兩個不相同的點的價值和

題解:dp[i]表示∑(i<j<=n)μ(i,j),因為對於路徑i,j,對於i<j<=a[i],為1,否則dis[i]=dis[a[m]]+1,m是i+1到a[i]中a[m]最大的,那麽轉移方程dp[i]=dp[m]+(n-i)-(a[i]-m),m的i+1到a[i]的a[m]最大值,這個可以用線段樹維護

仔細解釋一下轉移方程,dp[m]-(a[i]-m)就是要把m到a[i]的刪掉,因為這個地方從dp[m]可以一步到達,而在dp[i]中也能一步到達,對於i到m的地方dp[i]一步能到達,對於a[i]+1到n的地方,我們可以從dp[m]+1步來到達,所以轉移公式就是這麽來的

技術分享圖片
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=100000+10,maxn=2000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;

int a[N];
pair<ll,ll> maxx[N<<2];
ll dp[N];
void pushup(int rt)
{
    if(maxx[rt<<1].fi>maxx[rt<<1|1].fi)
        maxx[rt]=maxx[rt<<1];
    else
        maxx[rt]=maxx[rt<<1|1];
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        maxx[rt].fi=a[l];
        maxx[rt].se=l;
        return ;
    }
    int m=(l+r)>>1;
    build(ls);build(rs);
    pushup(rt);
}
pair<ll,ll> query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
        return maxx[rt];
    pair<ll,ll> ans,te;
    ans.fi=0;
    int m=(l+r)>>1;
    if(L<=m)
    {
        te=query(L,R,ls);
        if(ans.fi<te.fi)ans=te;
    }
    if(m<R)
    {
        te=query(L,R,rs);
        if(ans.fi<te.fi)ans=te;
    }
    return ans;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++)scanf("%d",&a[i]);
    a[n]=n;
    build(1,n,1);
//    for(int i=1;i<n;i++)cout<<query(i+1,a[i],1,n,1).se<<" ";
//    cout<<endl;
    dp[n]=0;
    for(int i=n-1;i>=1;i--)
    {
        int te=query(i+1,a[i],1,n,1).se;
//        printf("%d\n",te);
        dp[i]=dp[te]+n-i-(a[i]-te);
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
//        printf("%d ",dp[i]);
        ans+=dp[i];
    }
    printf("%lld\n",ans);
    return 0;
}
/********************

********************/
E

Codeforces Round #353 (Div. 2)