• Codeforces Round #416 (Div. 2)


    A.Vladik and Courtesy

    题目链接:http://codeforces.com/contest/811/problem/A

    暴力

    代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 typedef long long ll;
     4 ll a,b;
     5 int main(void){
     6     cin>>a>>b;
     7     ll t=1;
     8     while(1){
     9         if(t&1)a-=t;
    10         else b-=t;
    11         t++;
    12         if(a<0||b<0)break;
    13     }
    14     if(a<0)cout<<"Vladik";
    15     else cout<<"Valera";
    16 }
    View Code

    B.Vladik and Complicated Book

    题目链接:http://codeforces.com/contest/811/problem/B

    题目大意:判断区间内第$k$大元素是否为$x$.

    离线+树状数组/主席树模板/暴力

    看到数据范围$10^4$,想成学校的老年机,想半天想出个$O(mlgm+mlgn)$的,结果被告知$O(nm)$暴力可过= =

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 int n,m,a[10005],c[10005],f[10005];
     7 bool ans[10005];
     8 struct node{
     9     int l,r,x,id;
    10     friend bool operator<(node qq,node pp){
    11         return a[qq.x]<a[pp.x];
    12     }
    13 }q[10005];
    14 int lowbit(int x){
    15     return x&-x;
    16 }
    17 void add(int x){
    18     for(int i=x;i<=n;i+=lowbit(i))
    19         c[i]++;
    20 }
    21 int sum(int x){
    22     int ans=0;
    23     for(int i=x;i>0;i-=lowbit(i))
    24         ans+=c[i];
    25     return ans;
    26 }
    27 int main(void){
    28     scanf("%d%d",&n,&m);
    29     for(int i=1;i<=n;++i){
    30         scanf("%d",&a[i]);
    31         f[a[i]]=i;
    32     }
    33     for(int i=0;i<m;++i){
    34         scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x);
    35         q[i].id=i;
    36     }
    37     sort(q,q+m);
    38     int l=1;
    39     for(int i=0;i<m;++i){
    40         int id=q[i].id;
    41         while(l<a[q[i].x]){
    42             add(f[l]);
    43             l++;
    44         }
    45         int t=sum(q[i].r)-sum(q[i].l-1);
    46         if(q[i].l+t==q[i].x)ans[id]=1;
    47         else ans[id]=0;
    48     }
    49     for(int i=0;i<m;++i){
    50         if(ans[i])printf("Yes
    ");
    51         else printf("No
    ");
    52     }
    53 }
    View Code

    C.Vladik and Memorable Trip

    题目链接:http://codeforces.com/contest/811/problem/C

    题目大意:将一个数组划分成若干个不交叉的块,要求块外不含块内元素,每个块的价值为块内不同元素的异或值,总价值为所有块的价值和,问最大价值。

    DP

    想着先区间合并再dp,然后算法错误...

    看到数据范围其实$O(n^2)$可过,直接dp就好了...

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 typedef long long ll;
     7 int n,a[5005],dp[5005],r[5005];
     8 bool vis[5005],f[5005];
     9 int main(void){
    10     scanf("%d",&n);
    11     for(int i=0;i<n;++i){
    12         scanf("%d",&a[i]);
    13         r[a[i]]=i;
    14     }
    15     int ans=0;
    16     for(int i=0;i<n;++i){
    17         int t=a[i];
    18         if(!vis[t]){
    19             vis[t]=1;
    20             memset(f,0,sizeof(f));
    21             f[t]=1;
    22             bool flag=1;
    23             int temp=t;
    24             int R=r[t];
    25             for(int j=i+1;j<R;++j){
    26                 if(vis[a[j]]&&a[j]!=t){
    27                     flag=0;break;
    28                 }
    29                 if(!f[a[j]]){
    30                     temp^=a[j];
    31                     R=max(R,r[a[j]]);
    32                     f[a[j]]=1;
    33                 }
    34             }
    35             if(flag)dp[R]=max(dp[R],temp+ans);
    36         }
    37         ans=max(ans,dp[i]);
    38     }
    39     printf("%d
    ",ans);
    40 }
    View Code

    D.Vladik and Favorite Game

    题目链接:http://codeforces.com/contest/811/problem/D

    题目大意:交互题,要求输出从起点到终点的行动方向,其中左右和上下的方向可能会被改变一次。

    XJB模拟

    先dfs出不改变方向的情况下的原行动方向,然后一步一步模拟即可。

    代码如下:

      1 #include <cstdio>
      2 using namespace std;
      3 int n,m,d=-1,x,y,px,py,nx,ny;
      4 char mp[105][105];
      5 char ans[10005];
      6 bool vis[105][105];
      7 void dfs(int px,int py,int k){
      8     if(mp[px][py]=='F'){
      9         d=k;
     10         return;
     11     }
     12     int heng=0,shu=0;
     13     if(px-1>=0&&mp[px-1][py]!='*')shu++;
     14     if(px+1<n&&mp[px+1][py]!='*')shu++;
     15     if(py-1>=0&&mp[px][py-1]!='*')heng++;
     16     if(py+1<m&&mp[px][py+1]!='*')heng++;
     17     if(shu>heng){
     18         if(px-1>=0&&!vis[px-1][py]&&mp[px-1][py]!='*'){
     19             vis[px-1][py]=1;
     20             ans[k]='U';
     21             dfs(px-1,py,k+1);
     22             if(d!=-1)return;
     23         }
     24         if(px+1<n&&!vis[px+1][py]&&mp[px+1][py]!='*'){
     25             vis[px+1][py]=1;
     26             ans[k]='D';
     27             dfs(px+1,py,k+1);
     28             if(d!=-1)return;
     29         }
     30         if(py-1>=0&&!vis[px][py-1]&&mp[px][py-1]!='*'){
     31             vis[px][py-1]=1;
     32             ans[k]='L';
     33             dfs(px,py-1,k+1);
     34             if(d!=-1)return;
     35         }
     36         if(py+1<m&&!vis[px][py+1]&&mp[px][py+1]!='*'){
     37             vis[px][py+1]=1;
     38             ans[k]='R';
     39             dfs(px,py+1,k+1);
     40             if(d!=-1)return;
     41         }
     42     }else{
     43         if(py-1>=0&&!vis[px][py-1]&&mp[px][py-1]!='*'){
     44             vis[px][py-1]=1;
     45             ans[k]='L';
     46             dfs(px,py-1,k+1);
     47             if(d!=-1)return;
     48         }
     49         if(py+1<m&&!vis[px][py+1]&&mp[px][py+1]!='*'){
     50             vis[px][py+1]=1;
     51             ans[k]='R';
     52             dfs(px,py+1,k+1);
     53             if(d!=-1)return;
     54         }
     55         if(px-1>=0&&!vis[px-1][py]&&mp[px-1][py]!='*'){
     56             vis[px-1][py]=1;
     57             ans[k]='U';
     58             dfs(px-1,py,k+1);
     59             if(d!=-1)return;
     60         }
     61         if(px+1<n&&!vis[px+1][py]&&mp[px+1][py]!='*'){
     62             vis[px+1][py]=1;
     63             ans[k]='D';
     64             dfs(px+1,py,k+1);
     65             if(d!=-1)return;
     66         }
     67     }
     68 }
     69 char another(char c){
     70     if(c=='R')return 'L';
     71     if(c=='L')return 'R';
     72     if(c=='U')return 'D';
     73     if(c=='D')return 'U';
     74 }
     75 int main(void){
     76     scanf("%d%d",&n,&m);
     77     for(int i=0;i<n;++i)scanf("%s",mp[i]);
     78     dfs(0,0,0);
     79     px=nx=0,py=ny=0;
     80     bool heng=1,shu=1;
     81     for(int i=0;i<d;){
     82         bool LR=ans[i]=='L'||ans[i]=='R';
     83         bool UD=ans[i]=='U'||ans[i]=='D';
     84         if(LR){
     85             if(heng)printf("%c
    ",ans[i]);
     86             else printf("%c
    ",another(ans[i]));
     87             if(ans[i]=='R')ny=py+1;
     88             else ny=py-1;
     89         }else{
     90             if(shu)printf("%c
    ",ans[i]);
     91             else printf("%c
    ",another(ans[i]));
     92             if(ans[i]=='D')nx=px+1;
     93             else nx=px-1;
     94         }
     95         fflush(stdout);
     96         scanf("%d%d",&x,&y);x--,y--;
     97         if((x==-2&&y==-2)||mp[x][y]=='F')return 0;
     98         if(x==px&&y==py){
     99             if(ans[i]=='L'&&y+1>=m)heng=0;
    100             if(ans[i]=='R'&&y-1<0)heng=0;
    101             if(ans[i]=='D'&&x-1<0)shu=0;
    102             if(ans[i]=='U'&&x+1>=n)shu=0;
    103         }else if(x!=nx||y!=ny){
    104             if(ans[i]=='R'&&y!=ny){
    105                 heng=0;
    106                 printf("L
    ");
    107                 fflush(stdout);
    108                 scanf("%d%d",&x,&y);x--,y--;
    109             }
    110             if(ans[i]=='L'&&y!=ny){
    111                 heng=0;
    112                 printf("R
    ");
    113                 fflush(stdout);
    114                 scanf("%d%d",&x,&y);x--,y--;
    115             }
    116             if(ans[i]=='U'&&y!=ny){
    117                 shu=0;
    118                 printf("D
    ");
    119                 fflush(stdout);
    120                 scanf("%d%d",&x,&y);x--,y--;
    121             }
    122             if(ans[i]=='D'&&y!=ny){
    123                 shu=0;
    124                 printf("U
    ");
    125                 fflush(stdout);
    126                 scanf("%d%d",&x,&y);x--,y--;
    127             }
    128         }else i++;
    129         nx=px=x,ny=py=y;
    130     }
    131 }
    View Code

    E.Vladik and Entertaining Flags

    题目链接:http://codeforces.com/contest/811/problem/E

    题目大意:有一个$n imes m$的矩阵,$q$次询问,每次询问$l$列到$r$列围成的图中有多少连通块。

    线段树+并查集

    注意到$n leqslant 10$,故可以用线段树维护。

    每段维护从$L$列到$R$列的图中有多少连通块,以及$L$列及$R$列的段内数字编号(保证段内的联通的数字编号是相同的)。

    段与段合并时,只需判断相邻的数字是否相同,若相同且不为同一连通块,则合并。

    查询前,需要将段两端的数字编号的$pre$指向自己(build操作中有可能将$pre$指向了其他段中的数字编号;同时因为段内联通的数字编号相同,故该操作不会改变段内数字的连通性),之后同合并操作。

    复杂度$O(nmlgm+qnlgm)$.

    代码如下:

      1 #include <cstdio>
      2 #define lson x<<1,l,mid
      3 #define rson x<<1|1,mid+1,r
      4 using namespace std;
      5 int n,m,q,mp[12][100005],pre[1000005],tot;
      6 bool flag;
      7 struct node{
      8     int num;
      9     int L[12],R[12];
     10 }a[100005<<2],ans;
     11 void init(int x){
     12     for(int i=0;i<=x;++i)pre[i]=i;
     13 }
     14 int Find(int x){
     15     return pre[x]==x?x:pre[x]=Find(pre[x]);
     16 }
     17 void Union(int a,int b){
     18     int x=Find(a),y=Find(b);
     19     if(x!=y)pre[x]=y;
     20 }
     21 void push_up(int x,int mid){
     22     int l=x<<1,r=x<<1|1;
     23     a[x].num=a[l].num+a[r].num;
     24     for(int i=0;i<n;++i){
     25         if(mp[i][mid]==mp[i][mid+1]){
     26             if(Find(a[l].R[i])!=Find(a[r].L[i])){
     27                 a[x].num--;
     28                 Union(a[l].R[i],a[r].L[i]);
     29             }
     30         }
     31     }
     32     for(int i=0;i<n;++i){
     33         a[x].L[i]=Find(a[l].L[i]);
     34         a[x].R[i]=Find(a[r].R[i]);
     35     }
     36 }
     37 void build(int x,int l,int r){
     38     if(l==r){
     39         a[x].num=1;
     40         a[x].L[0]=a[x].R[0]=++tot;
     41         for(int i=1;i<n;++i){
     42             if(mp[i][r]==mp[i-1][r]){
     43                 a[x].L[i]=a[x].R[i]=tot;
     44             }else{
     45                 tot++,a[x].num++;
     46                 a[x].L[i]=a[x].R[i]=tot;
     47             }
     48         }
     49         return;
     50     }
     51     int mid=(l+r)>>1;
     52     build(lson);
     53     build(rson);
     54     push_up(x,mid);
     55 }
     56 void query(int x,int l,int r,int ql,int qr){
     57     if(ql<=l&&r<=qr){
     58         if(flag){
     59             flag=0;
     60             ans=a[x];
     61             return;
     62         }else{
     63             ans.num+=a[x].num;
     64             for(int i=0;i<n;++i){
     65                 pre[ans.R[i]]=ans.R[i];
     66                 pre[a[x].L[i]]=a[x].L[i];
     67                 pre[a[x].R[i]]=a[x].R[i];
     68             }
     69             for(int i=0;i<n;++i){
     70                 if(mp[i][l-1]==mp[i][l]){
     71                     if(Find(ans.R[i])!=Find(a[x].L[i])){
     72                         ans.num--;
     73                         Union(ans.R[i],a[x].L[i]);
     74                     }
     75                 }
     76             }
     77             for(int i=0;i<n;++i)
     78                 ans.R[i]=Find(a[x].R[i]);
     79             return;
     80         }
     81     }
     82     int mid=(l+r)>>1;
     83     if(ql<=mid)query(lson,ql,qr);
     84     if(mid<qr)query(rson,ql,qr);
     85 }
     86 int main(void){
     87     scanf("%d%d%d",&n,&m,&q);
     88     init(n*m);
     89     for(int i=0;i<n;++i)
     90         for(int j=0;j<m;++j)
     91             scanf("%d",&mp[i][j]);
     92     build(1,0,m-1);
     93     while(q--){
     94         int x,y;
     95         scanf("%d%d",&x,&y);x--;y--;
     96         flag=1;
     97         query(1,0,m-1,x,y);
     98         printf("%d
    ",ans.num);
     99     }
    100 }
    View Code
  • 相关阅读:
    BZOJ 1008 [HNOI2008]越狱
    BZOJ 1588 [HNOI2002]营业额统计
    20170520 DP阶段总结
    HDU 3507 Print Article
    浅谈随机数生成器及其应用
    BZOJ 1010 [HNOI2008]toy 玩具装箱
    斯堪福三定律
    这是我在博客园上的第一篇博客
    微博粉丝服务---“公众号”开发
    XML解析---利用XStream解析xml数据及反构造Java对象
  • 原文地址:https://www.cnblogs.com/barrier/p/6914277.html
Copyright © 2020-2023  润新知