【Educational Codeforces Round 22】

又打了一场EDU,感觉这场比23难多了啊……

艹还是我太弱了。

A.

随便贪心一下。

#include<bits/stdc++.h>
using namespace std;
int n,sum=0,ans=-1,m;
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();for(int i=1;i<=n;i++){int x=read();sum+=x;}m=read();
    while(m--){
        int l=read(),r=read();
        if(r>=sum){
            ans=max(l,sum);break;
        }
    }
    printf("%d\n",ans);
}

B.

预处理一下x,y的幂次就随便做了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll>a;
ll x,y,l,r,ans=0;
int main(){
    ios::sync_with_stdio(false);cin>>x>>y>>l>>r;
    a.push_back(l-1);a.push_back(r+1);
    for(ll i=1;;i*=x){
        for(ll j=1;;j*=y){
            ll len=i+j;
            if(len>=l&&len<=r)a.push_back(i+j);
            if(j>r/y)break;
        }
        if(i>r/x)break;
    }
    sort(a.begin(),a.end());
    for(ll i=1;i<a.size();i++)ans=max(ans,a[i]-a[i-1]-1);
    cout<<ans<<endl;
}

C.
推一下结论就行了。

#include<bits/stdc++.h>
#define N 200005
using namespace std;
int da[N],db[N],head[N],tot=0,n,x,ans=0;
struct Edge{int u,v,next;}G[N<<1];
inline void addedge(int u,int v){
    G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot;
    G[++tot].u=v;G[tot].v=u;G[tot].next=head[v];head[v]=tot;
}
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
void dfs(int u,int fa,int *d){
    for(int i=head[u];i;i=G[i].next){
        int v=G[i].v;if(v==fa)continue;
        d[v]=d[u]+1;
        dfs(v,u,d);
    }
}
int main(){
    n=read();x=read();
    for(int i=1;i<n;i++){
        int u=read(),v=read();
        addedge(u,v);
    }
    da[0]=db[0]=-1;dfs(1,0,da);dfs(x,0,db);
    for(int i=1;i<=n;i++)if(db[i]<da[i])ans=max(ans,2*da[i]);
    printf("%d\n",ans);
}

D.

按照官方题解做法dp一下就行。

#include<bits/stdc++.h>
#define N 5010
using namespace std;
int a[N],dp[N][N],cx[7],cy[100010],n,ans=0;
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();for(int i=1;i<=n;i++)a[i]=read();
    for(int i=0;i<=n;i++){
        memset(cx,0,sizeof(cx));memset(cy,0,sizeof(cy));
        for(int j=1;j<i;j++){
            cx[a[j]%7]=max(cx[a[j]%7],dp[i][j]);
            cy[a[j]]=max(cy[a[j]],dp[i][j]);
        }
        for(int j=i+1;j<=n;j++){
            dp[i][j]=dp[j][i]=max(max(cx[a[j]%7],dp[i][0]),max(cy[a[j]-1],cy[a[j]+1]))+1;
            ans=max(ans,dp[i][j]);
            cx[a[j]%7]=max(cx[a[j]%7],dp[i][j]);
            cy[a[j]]=max(cy[a[j]],dp[i][j]);
        }
    }
    printf("%d\n",ans);
}

E.
用动态开点线段树维护一下(因为值域过大)

#include<bits/stdc++.h>
#define N 100005
using namespace std;
int rt[N],a[N],cnt,n,k,m;
int sumv[N*70],ls[N*70],rs[N*70];
queue<int>q[N];
void ins(int &x,int pre,int l,int r,int q,int v){
    if(l>r)return;x=++cnt;sumv[x]=sumv[pre]+v;
    ls[x]=ls[pre];rs[x]=rs[pre];if(l==r)return;
    int mid=(l+r)>>1;
    if(q<=mid)ins(ls[x],ls[pre],l,mid,q,v);
    else ins(rs[x],rs[pre],mid+1,r,q,v);
}
int query(int o,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr)return sumv[o];
    int ans=0,mid=(l+r)>>1;
    if(ql<=mid)ans+=query(ls[o],l,mid,ql,qr);
    if(qr>mid)ans+=query(rs[o],mid+1,r,ql,qr);
    return ans;
}
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();k=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=n;i++){
        q[a[i]].push(i);ins(rt[i],rt[i-1],1,n,i,1);
        if(q[a[i]].size()>k){
            int tmp=q[a[i]].front();q[a[i]].pop();
            ins(rt[i],rt[i],1,n,tmp,-1);
        }
    }
    m=read();int ans=0;
    while(m--){
        int l=read(),r=read();
        l=(l+ans)%n+1;r=(r+ans)%n+1;
        if(l>r)swap(l,r);
        ans=query(rt[r],1,n,l,r);
        printf("%d\n",ans);
    }
}

F.

这tm做cf都能碰到原题,日哦。

bzoj4025。

可以分治并查集维护下(注意此时并查集不可以路径压缩)

或者直接LCT,参考2014集训队论文做法。

人懒就不码LCT了。

#include<bits/stdc++.h>
#define N 500005
using namespace std;
int n,m,t,fa[N],top,q[N<<2],d[N],a[N];
struct Edge{int x,y,l,r;}G[N];
inline int get(int x){
    while(fa[x]!=x)x=fa[x];
    return x;
}
inline int dis(int x){
    int ret=0;while(fa[x]!=x)ret^=a[x],x=fa[x];
    return ret;
}
inline void link(int x,int y,int v){
    if(d[x]>d[y])swap(x,y);if(d[x]==d[y])d[y]++,q[++top]=y;
    fa[x]=y;a[x]=v;q[++top]=x;
}
inline void erase(int x){
    for(;top>x;top--)if(q[top<0])d[-q[top]]--;
    else fa[q[top]]=q[top],a[q[top]]=0;
}
void solve(int l,int r,int k){
    int mid=(l+r)>>1,now=top;
    for(int i=1;i<=k;i++)if(G[i].l<=l&&r<=G[i].r){
        int u=get(G[i].x),v=get(G[i].y);
        if(u!=v)link(u,v,dis(G[i].x)==dis(G[i].y));
        else if(dis(G[i].x)==dis(G[i].y)){
            for(int i=l;i<=r;i++)puts("NO");erase(now);return;
        }
        swap(G[k--],G[i--]);
    }
    if(l==r)puts("YES");
    else{
        int i,j;for(i=1,j=0;i<=k;i++)if(G[i].l<=mid)swap(G[i],G[++j]);
        solve(l,mid,j);
        for(i=1,j=0;i<=k;i++)if(G[i].r>mid)swap(G[i],G[++j]);
        solve(mid+1,r,j);
    }
    erase(now);
}
map<int,int> mp[N];
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();t=read();
    for(int i=1;i<=t;i++){
        int x=read(),y=read();if(x>y)swap(x,y);
        if(mp[x][y])G[mp[x][y]].r=i-1,mp[x][y]=0;
        else{
            mp[x][y]=++m;G[m].x=x;G[m].y=y;G[m].l=i-1;G[m].r=t;
        }
    }
    for(int i=1;i<=m;i++)if(++G[i].l>G[i].r)i--,m--;
    for(int i=1;i<=n;i++)fa[i]=i,d[i]=1;
    solve(1,t,m);
}

总结:

思维能力亟待加强,还要多多cf

edu的难度比较符合我目前的水平,找个空多补一补。

时间: 2024-10-08 20:44:05

【Educational Codeforces Round 22】的相关文章

【Educational Codeforces Round 38】D. Buy a Ticket 堆优化Dijkstra

题意 给定一张无向图,对每个点$i\in S$求$\min_{j\in S} {2\times d(i,j)+a_j}$ 考虑多源多汇最短路会超时,换个角度考虑每个$j$,如果$j=i$,那么答案为$a_i$,如果有更优的方案,那么为$i$到$j$的一条路径加上$a_j$,将这个过程看成两条路径,并且将$a_j$独立为一条路径,就得到最短路算法中的松弛操作,可以建立一个超级源点,连向各点,边权为$a_i$,那么从源点跑一遍最短路之后就是每个点所求答案 时间复杂度$O(n\log n)$ 代码 #

【Educational Codeforces Round 37】F. SUM and REPLACE 线段树+线性筛

题意 给定序列$a_n$,每次将$[L,R]$区间内的数$a_i$替换为$d(a_i)$,或者询问区间和 这题和区间开方有相同的操作 对于$a_i \in (1,10^6)$,$10$次$d(a_i)$以内肯定可以最终化为$1$或者$2$,所以线段树记录区间最大值和区间和,$Max\le2$就返回,单点暴力更新,最后线性筛预处理出$d$ 时间复杂度$O(m\log n)$ 代码 #include <bits/stdc++.h> using namespace std; typedef long

Educational Codeforces Round 22 E. Army Creation(主席树)

题目链接:Educational Codeforces Round 22 E. Army Creation 题意: 给你n个数和一个数k,然后有q个询问. 每个询问 有一个区间[l,r],问你这个区间内在满足每一种数不超过k的情况下,最大能选多少个数出来. 强制在线. 题解: 一看就要用到主席树,和主席数求区间内有多少不同的数的个数处理方法相同. 依次将每个数插入,当这个数出现的个数等于k了,就把最前面的那个数删掉. 然后询问就访问root[r]就行了. 第一次写完数据结构没有调试一遍过样例,一

【Educational Codeforces Round 35 A】 Nearest Minimums

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 找出最小的数字的位置. 最近的肯定是相邻的某对. [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e5; int n; int a[N+10],mi; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", stdin); #endif io

【Educational Codeforces Round 35 D】Inversion Counting

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 排列中交换任意两个数字. 排列的逆序对个数的奇偶性会发生变化. 翻转这个过程其实就是len/2对数字发生交换. 交换了偶数次的话,不变,否则奇偶性发生改变. 先暴力求出一开始的逆序对个数就好 [代码] #include <bits/stdc++.h> using namespace std; const int N = 1500; int n,a[N+10],cnt,now,m; void out(int x){ if (x=

【Educational Codeforces Round 35 C】Two Cakes

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 直觉题. 感觉情况会很少. 毕竟间隔太大了.中间肯定有一些数字达不到. 有1肯定可以 2 2 x肯定可以 3 3 3也可以 2 4 4也可以. 就这样 [代码] #include <bits/stdc++.h> using namespace std; vector <int> v; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", &

【Educational Codeforces Round 36 A】 Garden

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举用哪一个桶就好 [代码] #include <bits/stdc++.h> using namespace std; int n,k,x; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", stdin); #endif ios::sync_with_stdio(0),cin.tie(0); cin >>

【Educational Codeforces Round 37 C】 Swap Adjacent Elements

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然l..r这一段连续的1可以把l..r+1变成有序的. 那么就把所有的连续1段变成有序的就好. 看看最后是不是升序即可. [代码] #include <bits/stdc++.h> using namespace std; const int N = 2e5; int n,a[N+10],b[N+10]; char s[N+10]; int main(){ #ifdef LOCAL_DEFINE freopen("

【Educational Codeforces Round 37 E】Connected Components?

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] bfs. 用一个链表来记录哪些点已经确定在某一个联通快里了. 一开始每个点都能用. 然后从第一个点开始进行bfs. 然后对于它的所有连接着的点(输入的图的补图 看看它是不是之前进行过bfs,如果是的话.就跳过.(可以用链表直接跳过.即沿着链表枚举它的出度. 否则.把这个点从链表中删掉.然后把这个点加入队列.继续bfs即可. 这样已经确定联通了的点之间不会再访问. 链表加速了寻找某个点的出度的过程. 且由于当n很大的时候.m只有2