Codeforces Round #433 (Div. 2) 题解

来源:互联网 发布:jk js 编辑:程序博客网 时间:2024/06/05 20:24

Codeforces Round #433 (Div. 2)

手。。。手速场?

A:

#include<bits/stdc++.h>using namespace std;typedef long long ll;int gcd(int a,int b) { return a%b?gcd(b,a%b):b; }int main(){    int n,a;    cin >> n;    for(a=n-1;a>=1;--a)        if(gcd(a,n-a)==1&&a<n-a) break;    cout << a << " " << n-a << endl;    return 0;}

B:

#include<bits/stdc++.h>using namespace std;typedef long long ll;int main(){    int n,k,ans1,ans2;    cin >> n >> k;    if(n==k||k==0) ans1=0;    else ans1=1;    if(n/3>=k) ans2=k*2;    else ans2=n-k;    cout << ans1 << " " << ans2 << endl;    return 0;}

C:
从值最大的开始贪心考虑,给它分配最优的时间。

#include<bits/stdc++.h>#define fi first#define se second#define mp make_pairusing namespace std;typedef long long ll;const int N=3e5+7;int a[N],b[N],p[N];set<int> s;int main(){    int n,k;    scanf("%d%d",&n,&k);    for(int i=0;i<n;++i) scanf("%d",&a[i]),p[i]=i,s.insert(i+k);    sort(p,p+n,[](int x,int y){ return a[x]>a[y]; });    ll ans=0;    for(int i=0;i<n;++i)    {        int id=p[i];        auto tmp = s.lower_bound(id);        b[id]=*tmp;        s.erase(tmp);        ans+=(ll)(b[id]-id)*a[id];    }    printf("%I64d\n",ans);    for(int i=0;i<n;++i) printf("%d%c",b[i]+1,i+1==n?'\n':' ');    return 0;}

D:
枚举共同工作的长度为 k 的区间,将出发航班和结束航班根据时间坐标放在 vector 里。这样区间每移动一格,可以处理出变化的信息。出发航班就取最小值就行。结束航班维护在 set 里。取当前 set 里的最小值。

#include<bits/stdc++.h>#define fi first#define se secondusing namespace std;typedef long long ll;const int N=1e5+7,K=1e6+7;typedef pair<int,int> pii;const ll INF = 1e18;multiset<int> s[N];vector<pii> arr[K],dep[K];int f[N];int main(){    int n,m,k;    scanf("%d%d%d",&n,&m,&k);    ++k;    for(int i=0;i<m;++i)    {        int d,f,t,c;        scanf("%d%d%d%d",&d,&f,&t,&c);        if(t==0) arr[d].push_back(make_pair(f,c));        else if(d>=k)        {            dep[d].push_back(make_pair(t,c));            s[t].insert(c);        }    }    bool ok=true;    ll res=0,ans=INF;    for(int i=1;i<=n;++i)    {        if(s[i].size()==0) ok=false;        res+=*s[i].begin();    }    if(!ok)    {        puts("-1");        return 0;    }    int cnt=0;    for(int i=1;i+k<=1000000;++i)    {        for(pii s : arr[i])        {            int id=s.fi;            int c=s.se;            if(f[id]==0) ++cnt,f[id]=c,res+=c;            if(c<f[id])            {                res=res-f[id]+c;                f[id]=c;            }        }        if(cnt==n)            ans=min(ans,res);        bool ok=true;        for(pii tmp : dep[i+k])        {            int id=tmp.fi;            int c=tmp.se;            res-=*s[id].begin();            s[id].erase(s[id].find(c));            if(s[id].size()==0) ok=false;            res+=*s[id].begin();        }        if(!ok) break;    }    if(ans==INF) puts("-1");    else printf("%I64d\n",ans);    return 0;}

E:
静态询问二维平面。很容易想到用主席树来进行降维。于是持久化 x 轴,建关于 y 轴的权值线段树。
每次询问可以转化为。于是就等于 n2+ 。询问四个边界相当于求一个二维平面被染色的点的数量,由于是离线,直接主席树就行。

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e5+7;int root[N],c[N*25],tot,ls[N*25],rs[N*25];void update(int &rt,int last,int l,int r,int p){    rt=++tot;    c[rt]=c[last]+1;    ls[rt]=ls[last];    rs[rt]=rs[last];    if(l==r) return ;    int m=(l+r)>>1;    if(p<=m) update(ls[rt],ls[last],l,m,p);    else update(rs[rt],rs[last],m+1,r,p);}int query(int rt1,int rt2,int l,int r,int ql,int qr){    if(ql<=l&&qr>=r) return c[rt2]-c[rt1];    int m=(l+r)>>1;    int res=0;    if(ql<=m) res+=query(ls[rt1],ls[rt2],l,m,ql,qr);    if(qr>m) res+=query(rs[rt1],rs[rt2],m+1,r,ql,qr);    return res;}ll f(ll x) { return x*(x-1)/2; }int main(){    int n,q;    scanf("%d%d",&n,&q);    int L=n+1;    for(int i=1;i<=n;++i)    {        int y;        scanf("%d",&y);        update(root[i],root[i-1],1,L,y);    }    while(q--)    {        int l,r,u,d;        scanf("%d%d%d%d",&l,&d,&r,&u);        ll ans=0;        ans=f(l-1)+f(d-1)+f(n-r)+f(n-u);        if(d>1) ans-=f(query(root[0],root[l-1],1,L,1,d-1));        if(d>1) ans-=f(query(root[r],root[n],1,L,1,d-1));        ans-=f(query(root[0],root[l-1],1,L,u+1,L));        ans-=f(query(root[r],root[n],1,L,u+1,L));        ans=f(n)-ans;        printf("%I64d\n",ans);    }    return 0;}
原创粉丝点击