Educational Codeforces Round 67 (Rated for Div. 2)补题


题目

A Stickers and Toys

#include<bits/stdc++.h>
using namespace std;
int main(){
    int p;
    scanf("%d",&p);
    while(p--){
    int n,s,t;
    scanf("%d%d%d",&n,&s,&t);
    int a,b,c;
    c=s+t-n;
    a=s-c;
    b=t-c;
    cout<<max(a,b)+1<<endl;
    }
}

B Letters Shop

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int>vec[26];
int pos[26];
int main(){
    scanf("%d",&n);
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++){
        vec[s[i]-'a'].push_back(i);
    }
    int q;
    scanf("%d",&q);
    while(q--){
        int ans=0;
        memset(pos,0,sizeof(pos));
        string tmp;
        cin>>tmp;
        for(int i=0;i<tmp.size();i++){
            ans=max(ans,vec[tmp[i]-'a'][pos[tmp[i]-'a']++]);
        }
        cout<<ans+1<<endl;
    }
}

C Vasya And Array

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
vector<pair<ll,ll> >vec,Vec[2];
bool L[maxn],R[maxn];
ll ans[maxn];
multiset<ll>s;
int main(){
    ll n,m;
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=m;i++){
        ll op,l,r;
        scanf("%lld%lld%lld",&op,&l,&r);
        if(!op)
        Vec[op].push_back(make_pair(l,r));
        if(op){
        vec.push_back(make_pair(l,-i));
        vec.push_back(make_pair(r,i));
        }
    }
    sort(vec.begin(),vec.end());
    ll sz=vec.size();
    ll curs,cure;
    for(ll i=0;i<sz;i++){
        if(vec[i].second<0){
            if(s.empty()){
                curs=vec[i].first;
                L[vec[i].first]=true;
            }
            s.insert(-vec[i].second);
        }
        else{
            s.erase(vec[i].second);
            if(s.empty()){
                R[vec[i].first]=true;
                cure=vec[i].first;
                Vec[1].push_back(make_pair(curs,cure));
            }
        }
    }
        bool flag=true;
    ll sz0=Vec[0].size();
    ll sz1=Vec[1].size();
    for(ll i=0;i<sz0;i++){
        for(ll j=0;j<sz1;j++){
            if(Vec[0][i].first>=Vec[1][j].first&&Vec[0][i].second<=Vec[1][j].second){
                flag=false;
                break;
            }
        }
        if(!flag)
            break;
    }
    if(!flag){
        puts("NO");
        return 0;
    }
    ll cur=1;
    flag=false;
    for(ll i=n;i>0;i--){
        if(R[i])flag=true;
        if(L[i])flag=false;
        if(flag)ans[i]=cur;
        else ans[i]=cur++;
    }
    puts("YES");
    for(ll i=1;i<=n;i++){
        printf("%lld%c",ans[i],i==n?'\n':' ');
    }
}

D Subarray Sorting

线段树最小值,枚举b中的数,判断当前b中的数是否为a中从1到该数在a中的位置这一区间内的最小值,并把a中这一数更新为INF

#include<bits/stdc++.h>
#define lson(x) x<<1
#define rson(x) x<<1|1
using namespace std;
const int maxn = 3e5+ 10;
const int INF=0x3f3f3f3f;
int a[maxn],b[maxn],pos[maxn];
struct Segment_tree
{
	int l, r, Min;
}tree[maxn<<2];
int n,m;
void push_up(int x) {
	tree[x].Min = min(tree[lson(x)].Min, tree[rson(x)].Min);
}
void build(int root, int l, int r) {
	tree[root].Min = INF;
	tree[root].l = l;
	tree[root].r = r;
	if (l == r) {
		tree[root].Min = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(lson(root), l, mid);
	build(rson(root), mid + 1, r);
	push_up(root);
}
void update(int root, int pos, int val) {
	if (tree[root].l == tree[root].r) {
		tree[root].Min = val;
		return;
	}
	int mid = (tree[root].l + tree[root].r) >>1;
	if (pos<=mid)
		update(lson(root), pos, val);
	else
		update(rson(root), pos, val);
	push_up(root);
}
int querymin(int root, int l, int r) {
	if (tree[root].l >=l&& tree[root].r<=r) {
		return tree[root].Min;
	}
	int mid = (tree[root].l + tree[root].r) >>1;
	if (r <= mid)
		return querymin(lson(root), l, r);
	else if (l > mid)
		return querymin(rson(root), l, r);
	else
		return min(querymin(lson(root), l, mid), querymin(rson(root), mid + 1, r));
}
vector<int>A[maxn],B[maxn];
int main() {
    int t;
    scanf("%d",&t);
	while (t--) {
        scanf("%d", &n);
        for(int i=1;i<=n;i++)A[i].clear(),B[i].clear();
        for (int i = 1; i <= n; i++){
			scanf("%d", &a[i]);
			A[a[i]].push_back(i);
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&b[i]);
            B[b[i]].push_back(i);
        }
        bool flag=true;
        for(int i=1;i<=n;i++){
            if(A[i].size()!=B[i].size()){
                flag=false;
                break;
            }
            for(int j=0;j<A[i].size();j++){
                pos[B[i][j]]=A[i][j];
            }
        }
        if(!flag){puts("NO");continue;}
		build(1, 1, n);
		for(int i=1;i<=n;i++){
            if(querymin(1,1,pos[i])!=b[i]){
                    //cout<<b[i]<<' '<<querymin(1,1,pos[b[i]])<<endl;
                flag=false;
                break;
            }
            update(1,pos[i],INF);
		}
		if(flag)puts("YES");
		else puts("NO");
	}
	return 0;
}

E Tree Painting

选取跟使求子树大小和最大,换根dp,先任选一个根求出答案,然后可推出相邻点为根的答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
struct Edge{
    ll v,next;
}e[maxn<<1];
ll head[maxn];
ll ans[maxn];
ll sz[maxn];
ll cnt;
ll Ans;
void add(ll u,ll v){
    e[cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
void getsize(ll u,ll f){
    sz[u]=1;
    for(ll i=head[u];~i;i=e[i].next){
        ll v=e[i].v;
        if(v==f)continue;
        getsize(v,u);
        sz[u]+=sz[v];
    }
    ans[1]+=sz[u];
}
void getans(ll u,ll f){
    for(ll i=head[u];~i;i=e[i].next){
        ll v=e[i].v;
        if(v==f)continue;
        ans[v]=ans[u]-sz[u]-sz[v];
        ll szu=sz[u],szv=sz[v];
        sz[v]=szu;
        sz[u]=szu-szv;
        ans[v]+=sz[v]+sz[u];
        getans(v,u);
        sz[v]=szv;
        sz[u]=szu;
    }
    Ans=max(Ans,ans[u]);
}
int main(){
    memset(head,-1,sizeof(head));
    ll n;
    scanf("%lld",&n);
    for(ll i=1;i<n;i++){
        ll u,v;
        scanf("%lld%lld",&u,&v);
        add(u,v);
        add(v,u);
    }
    getsize(1,-1);
    getans(1,-1);
    cout<<Ans<<endl;
}
发布了29 篇原创文章 · 获赞 4 · 访问量 675

猜你喜欢

转载自blog.csdn.net/qq_44290978/article/details/104082620