• Educational Codeforces Round 62 做题记录


    A.

    题解:

    发现就是找前缀 max = i 的点的个数,暴力扫一遍

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define pii pair<int,int>
     4 #define mp(a,b) make_pair(a,b)
     5 using namespace std;
     6 #define maxn 10005
     7 int n;
     8 int a[maxn];
     9 int main()
    10 {
    11     scanf("%d",&n);
    12     for(int i=1;i<=n;++i)
    13     {
    14         scanf("%d",&a[i]);
    15     }
    16     int ans=0,last=0;
    17     for(int i=1;i<=n;++i)
    18     {
    19         last=max(a[i],last);
    20         if(i>=last)ans++;
    21     }
    22     printf("%d
    ",ans);
    23     return 0;
    24 }
    View Code

    B.

    题解:

    找到最左边的>,删去其左边的<;

    或找到最右边的<,删去其右边的>;

    两种方法取最优

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define pii pair<int,int>
     4 #define mp(a,b) make_pair(a,b)
     5 using namespace std;
     6 #define maxn 105
     7 int T,n;
     8 char s[maxn];
     9 int main()
    10 {
    11     scanf("%d",&T);
    12     while(T--)
    13     {
    14         scanf("%d",&n);
    15         scanf("%s",s+1);
    16         int ans=n-1;
    17         for(int i=1;i<=n;++i)if(s[i]=='>')ans=min(ans,i-1);
    18         for(int i=n;i>=1;--i)if(s[i]=='<')ans=min(ans,n-i);
    19         printf("%d
    ",ans);
    20     }
    21     return 0;
    22 }
    View Code

    C.

    题解:

    我们将元素按b排序,从大往小加入

    显然当前b为最小,已经固定

    考虑找前k大的t,用优先队列维护就行

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define pii pair<int,int>
     4 #define mp(a,b) make_pair(a,b)
     5 using namespace std;
     6 #define maxn 300005
     7 int n,k;
     8 struct data
     9 {
    10     ll t,b;
    11 }a[maxn];
    12 bool operator < (data A,data B)
    13 {
    14     return A.b>B.b;
    15 }
    16 priority_queue<ll,vector<ll>,greater<ll>> pq;
    17 int main()
    18 {
    19     scanf("%d%d",&n,&k);
    20     for(int i=1;i<=n;++i)scanf("%I64d%I64d",&a[i].t,&a[i].b);
    21     sort(a+1,a+n+1);
    22     int sz=0;
    23     ll sum=0,ans=0;
    24     for(int i=1;i<=n;++i)
    25     {
    26         if(sz<k)
    27         {
    28             sz++;
    29             pq.push(a[i].t);sum+=a[i].t;
    30             ans=max(ans,sum*a[i].b);
    31         }
    32         else
    33         {
    34             sum+=a[i].t; pq.push(a[i].t);
    35             ll x=pq.top();pq.pop();
    36             sum-=x;
    37             ans=max(ans,sum*a[i].b);
    38         }
    39     }
    40     printf("%I64d
    ",ans);
    41     return 0;
    42 }
    View Code

    D.

    题解:

    观察发现,ans=2*3+3*4+4*5+……+(n-1)*n

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define pii pair<int,int>
     4 #define mp(a,b) make_pair(a,b)
     5 using namespace std;
     6 int n;
     7 int main()
     8 {
     9     scanf("%d",&n);
    10     ll ans=0;
    11     for(int i=2;i<n;++i)
    12     {
    13         ans+=1ll*i*(i+1);
    14     }
    15     printf("%I64d
    ",ans);
    16     return 0;
    17 }
    View Code

    E.

    题解:

    考虑题目给定的条件,不能出现奇数回文串等价于不能出现a[i]==a[i-2]的情况

    按奇偶分类,取分类完的序列A,长度为len

    等价于每个-1可以染k种颜色,不能出现相邻两个格子染色相同

    如果A中没有已经确定的数,那么ans=k*(k-1)^(len-1)

    如果A中有一个已经确定的数,那么ans=(k-1)^(len-1)

    如果A中>=2个已确定的数,那么左右两端同上述情况,中间的就是一个经典的染色DP

    f ( i , 0 )表示两端数字不同时,i和结尾不同的方案数

    f ( i , 1 )表示两端数字不同时,i和结尾相同的方案数

    g ( i , 0 )表示两端数字相同时,i和结尾不同的方案数

    g ( i , 1 )表示两端数字相同时,i和结尾相同的方案数

     转移显然

    细节和边界条件比较多,比赛时候写错一个小地方WA到死qwq

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 #define pii pair<int,int>
      4 #define mp(a,b) make_pair(a,b)
      5 using namespace std;
      6 #define maxn 200005
      7 const ll mod = 998244353;
      8 ll f[maxn][2],g[maxn][2];
      9 ll fastpow(ll a,ll p)
     10 {
     11     ll ans=1;
     12     while(p)
     13     {
     14         if(p&1)ans=ans*a%mod;
     15         a=a*a%mod;p>>=1; 
     16     }
     17     return ans;
     18 }
     19 ll work(ll *a,int n,ll k)
     20 {
     21     for(int i=2;i<=n;++i)if(a[i]==a[i-1]&&a[i]!=-1)return 0;
     22     int p=0;
     23     for(int i=1;i<=n;++i)if(a[i]!=-1)p++;
     24     if(!p)
     25     {
     26         return fastpow(k-1,n-1)*k%mod;
     27     }
     28     else if(p==1)
     29     {
     30         return fastpow(k-1,n-1);
     31     }
     32     else
     33     {
     34         if(p==n)return 1;
     35         if(k==1)return 0;
     36         ll res=1;
     37         int l,r;
     38         for(int i=1;i<=n;++i)
     39         {
     40             if(a[i]!=-1)
     41             {
     42                 l=i+1;
     43                 break;
     44             }
     45             res=res*(k-1)%mod;
     46         }
     47         for(int i=n;i;--i)
     48         {
     49             if(a[i]!=-1)
     50             {
     51                 r=i-1;
     52                 break;
     53             }
     54             res=res*(k-1)%mod;
     55         }
     56         ll t=0;
     57         ll last=a[l-1];
     58         for(int i=l;i<=r+1;++i)
     59         {
     60             if(a[i]!=-1)
     61             {
     62                 if(!t)
     63                 {
     64                     last=a[i];
     65                     continue;
     66                 }
     67                 if(a[i]!=last)res=(res*f[t][0])%mod;
     68                 else res=(res*g[t][0])%mod;
     69                 t=0;last=a[i];
     70             }
     71             else t++;
     72         }
     73         return res;
     74     }
     75 }
     76 int n,cnt1,cnt2;
     77 ll k;
     78 ll a[maxn],b[maxn],c[maxn];
     79 int main()
     80 {
     81     scanf("%d%I64d",&n,&k);
     82     for(int i=1;i<=n;++i)
     83     {
     84         scanf("%I64d",&a[i]);
     85     }
     86     f[1][0]=k-2;f[1][1]=1;
     87     g[1][0]=k-1;g[1][1]=0;
     88     for(int i=2;i<=n;++i)
     89     {
     90         f[i][0]=(f[i-1][0]*(k-2)%mod+f[i-1][1]*(k-1)%mod)%mod;
     91         f[i][1]=f[i-1][0];
     92         g[i][0]=(g[i-1][0]*(k-2)%mod+g[i-1][1]*(k-1)%mod)%mod;
     93         g[i][1]=g[i-1][0];
     94     }
     95     for(int i=1;i<=n;i+=2)b[++cnt1]=a[i];
     96     for(int i=2;i<=n;i+=2)c[++cnt2]=a[i];
     97     ll ans=work(b,cnt1,k);
     98     ans=ans*work(c,cnt2,k)%mod;
     99     printf("%I64d
    ",ans);
    100     return 0;
    101 }
    View Code

    F.

    题解:

    考虑把横坐标看成点,纵坐标看成点,每次加入一对数相当于连边

    然后R的大小就是连通块中横点个数*纵点个数

    动态图连通性

    离线下来分治线段树,用可撤销并查集维护

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 #define pii pair<int,int>
      4 #define mp(a,b) make_pair(a,b)
      5 #define maxn 600005
      6 using namespace std;
      7 int q,n=300000;
      8 struct Edg
      9 {
     10     int x,y;
     11 }a[maxn],b[maxn];
     12 int c[maxn],last[maxn];
     13 struct Option
     14 {
     15     int l,r,x,y;
     16 }opt[maxn];
     17 bool operator < (Edg A,Edg B)
     18 {
     19     if(A.x==B.x)return A.y<B.y;
     20     return A.x<B.x;
     21 }
     22 bool operator == (Edg A,Edg B)
     23 {
     24     return (A.x==B.x&&A.y==B.y);
     25 }
     26 int fa[maxn],sz1[maxn],sz2[maxn],size[maxn];
     27 int find(int x)
     28 {
     29     while(fa[x]!=x)x=fa[x];
     30     return x;
     31 }
     32 vector<pii> ve[maxn<<2];
     33 void add(int rt,int l,int r,int ql,int qr,pii x)
     34 {
     35     if(ql<=l&&r<=qr)
     36     {
     37         ve[rt].push_back(x);
     38         return;
     39     }
     40     int mid=(l+r)>>1;
     41     if(ql<=mid)add(rt<<1,l,mid,ql,qr,x);
     42     if(qr>mid)add(rt<<1|1,mid+1,r,ql,qr,x);
     43 }
     44 int s1[maxn],s2[maxn],top;
     45 ll Ans[maxn],res=0;
     46 void dfs(int rt,int l,int r)
     47 {
     48     if(l>r)return;
     49     int bot=top;
     50     for(int i=0;i<ve[rt].size();++i)
     51     {
     52         int u=ve[rt][i].first,v=ve[rt][i].second;
     53         if(find(u)==find(v))continue;
     54         u=find(u),v=find(v);
     55         if(size[u]<size[v])swap(u,v);
     56         res-=1ll*sz1[u]*sz2[u]+1ll*sz1[v]*sz2[v];
     57         fa[v]=u;
     58         size[u]+=size[v];sz1[u]+=sz1[v],sz2[u]+=sz2[v];
     59         s1[++top]=v;s2[top]=u;
     60         res+=1ll*sz1[u]*sz2[u];
     61     }
     62     if(l==r)
     63     {
     64         Ans[l]=res;
     65     }
     66     int mid=(l+r)>>1;
     67     if(l!=r)
     68     {
     69         dfs(rt<<1,l,mid);
     70         dfs(rt<<1|1,mid+1,r);
     71     }
     72     while(top>bot)
     73     {
     74         int u=s1[top],v=s2[top];
     75         res-=1ll*sz1[v]*sz2[v];
     76         fa[u]=u;
     77         size[v]-=size[u];sz1[v]-=sz1[u];sz2[v]-=sz2[u];
     78         res+=1ll*sz1[u]*sz2[u]+1ll*sz1[v]*sz2[v];
     79         top--;
     80     }
     81 }
     82 int main()
     83 {
     84     scanf("%d",&q);
     85     for(int i=1;i<=q;++i)
     86     {
     87         scanf("%d%d",&a[i].x,&a[i].y);
     88         a[i].y+=n;
     89         b[i]=a[i];
     90     }
     91     sort(a+1,a+q+1);
     92     int d=unique(a+1,a+q+1)-a-1;
     93     for(int i=1;i<=q;++i)c[i]=lower_bound(a+1,a+d+1,b[i])-a;
     94     int cnt=0;
     95     for(int i=1;i<=q;++i)
     96     {
     97         if(!last[c[i]])last[c[i]]=i;
     98         else
     99         {
    100             ++cnt;
    101             opt[cnt].l=last[c[i]],opt[cnt].r=i-1,opt[cnt].x=a[c[i]].x,opt[cnt].y=a[c[i]].y;
    102             last[c[i]]=0;
    103         }
    104     }
    105     for(int i=1;i<=d;++i)if(last[i])
    106     {
    107         ++cnt;
    108         opt[cnt].l=last[i],opt[cnt].r=q,opt[cnt].x=a[i].x,opt[cnt].y=a[i].y;
    109         last[i]=0;
    110     }
    111     for(int i=1;i<=cnt;++i)add(1,1,q,opt[i].l,opt[i].r,mp(opt[i].x,opt[i].y));
    112     for(int i=1;i<=n;++i)fa[i]=i,sz1[i]=1,size[i]=1;
    113     for(int i=1;i<=n;++i)fa[i+n]=i+n,sz2[i+n]=1,size[i+n]=1;
    114     dfs(1,1,q);
    115     for(int i=1;i<=q;++i)printf("%I64d ",Ans[i]);
    116     return 0;
    117 }
    View Code

    G.

    题解:

    类似于ZJOI的某道题,多次询问两点最短路

    一样的思路,分治最短路

    分治改成树分治就好了

    (这F和G怎么都是胖题)

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 #define maxn 600005
      4 using namespace std;
      5 int n,q;
      6 vector<int> T[maxn];
      7 int root;
      8 namespace Tree
      9 {
     10     struct edge
     11     {
     12         int to,next;
     13     }e[maxn<<1];
     14     int head[maxn],p;
     15     int cnt;
     16     void addedge(int u,int v)
     17     {
     18         e[++p].to=v;e[p].next=head[u];head[u]=p;
     19         e[++p].to=u;e[p].next=head[v];head[v]=p;
     20     }
     21     int rt,nowsize;
     22     bool del[maxn];
     23     int sum[maxn],f[maxn];
     24     void getroot(int u,int fa)
     25     {
     26         sum[u]=1;f[u]=0;
     27         for(int i=head[u];i;i=e[i].next)
     28         {
     29             int v=e[i].to;
     30             if(v==fa||del[v])continue;
     31             getroot(v,u);
     32             sum[u]+=sum[v];
     33             if(sum[v]>f[u])f[u]=sum[v];
     34         }
     35         f[u]=max(f[u],nowsize-sum[u]);
     36         if(f[u]<f[rt])rt=u;
     37     }
     38     void solve(int u)
     39     {
     40         del[u]=1;
     41         for(int i=head[u];i;i=e[i].next)
     42         {
     43             int v=e[i].to;
     44             if(del[v])continue;
     45             rt=0;
     46             f[rt]=nowsize=sum[v];
     47             getroot(v,0);
     48             T[u].push_back(rt);
     49             T[u+1].push_back(rt+1); 
     50             solve(rt);
     51         }
     52     }
     53     void work()
     54     {
     55         rt=0;
     56         f[rt]=nowsize=n;
     57         getroot(1,0);
     58         root=rt;
     59         solve(rt);
     60     }
     61 };
     62 namespace Graph
     63 {
     64     const ll inf = (ll)2e18;
     65     struct Query
     66     {
     67         int u,v,id;
     68         Query(){}
     69         Query(int U,int V,int ID){u=U;v=V;id=ID;}
     70     };
     71     ll Ans[maxn];
     72     vector<Query> vq[maxn];
     73     struct edge
     74     {
     75         int to,next;
     76         ll w;
     77     }e[maxn<<2];
     78     bool used[maxn];
     79     bool del[maxn];
     80     int head[maxn],p;
     81     void addedge(int u,int v,ll w)
     82     {
     83         e[++p].to=v;e[p].w=w;e[p].next=head[u];head[u]=p;
     84         e[++p].to=u;e[p].w=w;e[p].next=head[v];head[v]=p;
     85     }
     86     struct node
     87     {
     88         int x;ll dis;
     89         node(){}
     90         node(int id,ll d){x=id;dis=d;}
     91     };
     92     bool operator < (node a,node b)
     93     {
     94         return a.dis>b.dis;
     95     }
     96     ll dis[maxn];
     97     void dijkstra(int s)
     98     {
     99         priority_queue<node> q;
    100         q.push(node(s,0));dis[s]=0;
    101         while(!q.empty())
    102         {
    103             int u=q.top().x;q.pop();
    104             if(used[u])continue;
    105             used[u]=1;
    106             for(int i=head[u];i;i=e[i].next)if(!del[e[i].to])
    107             {
    108                 int v=e[i].to;
    109                 ll w=e[i].w;
    110                 if(dis[v]>dis[u]+w)
    111                 {
    112                     dis[v]=dis[u]+w;
    113                     q.push(node(v,dis[v]));
    114                 }
    115             }
    116         }
    117     }
    118     int belong[maxn];
    119     void clear(int u)
    120     {
    121         dis[u]=inf;used[u]=0;
    122         for(int i=0;i<T[u].size();++i)clear(T[u][i]);
    123     }
    124     void get_belong(int u,int rt,int tp)
    125     {
    126         belong[u]=rt+tp;
    127         for(int i=0;i<T[u].size();++i)
    128         {
    129             int v=T[u][i];
    130             get_belong(v,rt,tp);
    131         }
    132     }
    133     void dfs(int rt)
    134     {
    135         if(!vq[rt].size())return;
    136         clear(rt);
    137         clear(rt+1);
    138         dijkstra(rt);
    139         for(int i=0;i<vq[rt].size();++i)
    140         {
    141             int u=vq[rt][i].u,v=vq[rt][i].v;
    142             Ans[vq[rt][i].id]=min(Ans[vq[rt][i].id],dis[u]+dis[v]);
    143         }
    144         clear(rt);
    145         clear(rt+1);
    146         dijkstra(rt+1);
    147         for(int i=0;i<vq[rt].size();++i)
    148         {
    149             int u=vq[rt][i].u,v=vq[rt][i].v;
    150             Ans[vq[rt][i].id]=min(Ans[vq[rt][i].id],dis[u]+dis[v]);
    151         }
    152         del[rt]=1;del[rt+1]=1;
    153         for(int i=0;i<T[rt].size();++i)get_belong(T[rt][i],T[rt][i],0);
    154         for(int i=0;i<T[rt+1].size();++i)get_belong(T[rt+1][i],T[rt+1][i],-1);
    155         for(int i=0;i<vq[rt].size();++i)
    156         {
    157             int u=vq[rt][i].u,v=vq[rt][i].v;
    158             if(u==rt||v==rt||u==rt+1||v==rt+1)continue;
    159             if(belong[u]==belong[v])vq[belong[u]].push_back(vq[rt][i]);
    160         }
    161         for(int i=0;i<T[rt].size();++i)dfs(T[rt][i]);
    162     }
    163     void work()
    164     {
    165         Tree::work();
    166         for(int i=1;i<=q;++i)
    167         {
    168             int u,v;
    169             scanf("%d%d",&u,&v);
    170             vq[root].push_back(Query(u,v,i));
    171             Ans[i]=inf;
    172         }
    173         dfs(root);
    174         for(int i=1;i<=q;++i)printf("%I64d
    ",Ans[i]);
    175     }
    176 }
    177 int main()
    178 {
    179     scanf("%d",&n);
    180     for(int i=1;i<=n;++i)
    181     {
    182         ll w;
    183         scanf("%I64d",&w);
    184         Graph::addedge(i*2-1,i*2,w);
    185     }
    186     for(int i=1;i<n;++i)
    187     {
    188         int x,y;ll w1,w2;
    189         scanf("%d%d%I64d%I64d",&x,&y,&w1,&w2);
    190         Graph::addedge(x*2-1,y*2-1,w1);
    191         Graph::addedge(x*2,y*2,w2);
    192         Tree::addedge(x*2-1,y*2-1);
    193     }
    194     scanf("%d",&q); 
    195     Graph::work();
    196     return 0;
    197 }
    View Code
  • 相关阅读:
    maven打包成jar文件与打包成tar.gz文件
    maven命令错误:-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME
    Nginx监听多个端口配置实例 Linux
    怎么修改redis-cli访问的地址
    eclipse的.properties文件中文显示问题
    Linux关闭防火墙命令red hat/CentOs7
    CentOS 7防火墙快速开放端口配置方法
    Window下Beego环境搭建和bee工具使用
    .netcore2.1 使用middleware对api请求头进行验证
    .netcore2.1 统一接口返回属性名称
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10585235.html
Copyright © 2020-2023  润新知