zoukankan      html  css  js  c++  java
  • vijos国庆节模拟赛之繁星春水

    A.闪烁的繁星

    题目:https://vijos.org/p/1881

    题解:貌似做过小白逛公园或者序列操作都可以秒出吧,就是pushup函数比较麻烦,不过仔细想一想就知道了。

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define maxn 250000+1510
    13 #define maxm 500+100
    14 #define eps 1e-10
    15 #define ll long long
    16 #define pa pair<int,int>
    17 #define for0(i,n) for(int i=0;i<=(n);i++)
    18 #define for1(i,n) for(int i=1;i<=(n);i++)
    19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    21 #define mod 1000000007
    22 using namespace std;
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    27     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 int n,m;
    31 struct seg{int l,r,ls,rs,lx,rx,mx;}t[4*maxn];
    32 void build(int k,int l,int r)
    33 {
    34     t[k].l=l;t[k].r=r;t[k].lx=t[k].rx=t[k].mx=t[k].ls=t[k].rs=1;
    35     if(l==r)return;
    36     int mid=(l+r)>>1;
    37     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    38 }
    39 void pushup(int k)
    40 {
    41     int l=k<<1,r=k<<1|1,mid=(t[k].l+t[k].r)>>1;
    42     t[k].ls=t[l].ls;t[k].rs=t[r].rs;
    43     t[k].lx=t[l].lx;
    44     t[k].rx=t[r].rx;
    45     t[k].mx=max(t[l].mx,t[r].mx);
    46     if(t[l].rs!=t[r].ls)
    47      {
    48       t[k].mx=max(t[k].mx,t[l].rx+t[r].lx);
    49       if(t[l].mx==mid-t[k].l+1)t[k].lx=max(t[k].lx,t[l].mx+t[r].lx);
    50       if(t[r].mx==t[k].r-mid)t[k].rx=max(t[k].rx,t[r].mx+t[l].rx);
    51      }
    52     //cout<<t[k].l<<' '<<t[k].r<<' '<<t[k].ls<<' '<<t[k].rs<<' '<<t[k].lx<<' '<<t[k].rx<<' '<<t[k].mx<<endl; 
    53 }
    54 void change(int k,int x)
    55 {
    56     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
    57     if(l==r){t[k].rs=1-t[k].rs;t[k].ls=t[k].rs;return;}
    58     if(x<=mid)change(k<<1,x);else change(k<<1|1,x);
    59     pushup(k);
    60 }
    61 int main()
    62 {
    63     freopen("input.txt","r",stdin);
    64     freopen("output.txt","w",stdout);
    65     n=read();m=read();
    66     build(1,1,n);
    67     while(m--)change(1,read()),printf("%d
    ",t[1].mx);
    68     return 0;
    69 }
    View Code

    B.石阶上的砖

    题目:https://vijos.org/p/1882

    题解:这种题我居然没有做出来T_T

            正解是把每个数减去它的相对高度之后降问题转化为一个单变量绝对值和的最小值,显然是中位数。。。

            为何我考试的时候以为是神题就放弃了。。。

            以后碰到带绝对值的就往中位数想!

    代码:(考场上的sb骗分)

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000000000
    13 #define maxn 500000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline ll read()
    25 {
    26     ll x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 ll n,ans,a[2][maxn];
    32 ll f(ll x){return x>0?x:-x;}
    33 inline ll check(ll x)
    34 {
    35     ll t=0;
    36     for0(i,1)
    37      for1(j,n)
    38       t+=f(a[i][j]-(x+f(j-(n+1)/2)));
    39     return t;
    40 }
    41 int main()
    42 {
    43     freopen("input.txt","r",stdin);
    44     freopen("output.txt","w",stdout);
    45     n=read();
    46     for0(i,1)
    47      for1(j,n)
    48       a[i][j]=read();
    49     ans=inf;  
    50     for0(i,1)
    51      for1(j,n)
    52       ans=min(ans,check(a[i][j]));
    53     printf("%lld
    ",ans);  
    54     return 0;
    55 }
    View Code

    代码:(正解)

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 1000000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline ll read()
    25 {
    26     ll x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 ll n,a[2*maxn];
    32 inline ll f(ll x){return x>0?x:-x;}
    33 int main()
    34 {
    35     freopen("input.txt","r",stdin);
    36     freopen("output.txt","w",stdout);
    37     n=read();
    38     for1(i,n)a[i]=read()-f(i-(n+1)/2);
    39     for1(i,n)a[n+i]=read()-f(i-(n+1)/2);
    40     sort(a+1,a+2*n+1);
    41     ll ans=0;
    42     for1(i,2*n)ans+=f(a[i]-a[n]);
    43     printf("%lld
    ",ans);
    44     return 0;
    45 }
    View Code

    C.月光的魔法

    题目:https://vijos.org/p/1883

    题解:这题比较有意思,考场上大部分时间都在想这题。

            每个圆本来只能增加1个平面
            会出现更多 是因为一些圆首尾相接把一个大圆割成了两部分

            先把圆转化为线段

            找出每个圆的第一个祖先

            意思就是 完全包含而又最小的圆
            然后按左端点递增,左端点相同则右端点越远越优先排序

            然后我yy了一个dfs,是这样的

    1 void dfs(int x)
    2 {
    3     while(m<=n&&a[m].y<=a[x].y)
    4      {
    5          fa[m]=x;
    6          m++;
    7          dfs(m-1);
    8      }
    9 }

          因为右端点比x小,而且左端点在x右边的圆一定被x完全包含,而我们只需要一级,所以把这个过程递归下去。

         然后就可以求出每个点i的fa[i]了

         然后这样扫一遍

    1     for1(i,n)s[fa[i]]+=a[i].y-a[i].x;
    2     int ans=n+1;
    3     for1(i,n)if(s[i]==a[i].y-a[i].x)ans++;

         此题就over了。

         不知神犇们还有什么更好的方法,我感觉我的方法比较猎奇。。。

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 100000000000
    13 #define maxn 500000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline ll read()
    25 {
    26     ll x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 struct rec{ll x,y;}a[maxn];
    32 int n,m,ans,fa[maxn];
    33 ll s[maxn];
    34 inline bool cmp(rec a,rec b)
    35 {
    36     return a.x<b.x||(a.x==b.x&&a.y>b.y);
    37 }
    38 void dfs(int x)
    39 {
    40     while(m<=n&&a[m].y<=a[x].y)
    41      {
    42          fa[m]=x;
    43          m++;
    44          dfs(m-1);
    45      }
    46 }
    47 int main()
    48 {
    49     freopen("input.txt","r",stdin);
    50     freopen("output.txt","w",stdout);
    51     n=read();
    52     for1(i,n)
    53     {
    54         ll x=read(),y=read();
    55         a[i].x=x-y;a[i].y=x+y;
    56     }
    57     sort(a+1,a+n+1,cmp);
    58     m=1;
    59     a[0].y=inf;
    60     dfs(0);
    61     for1(i,n)s[fa[i]]+=a[i].y-a[i].x;
    62     int ans=n+1;
    63     for1(i,n)if(s[i]==a[i].y-a[i].x)ans++;
    64     printf("%d
    ",ans);
    65     return 0;
    66 }
    View Code

    D.诗情

    题目:https://vijos.org/p/1884

    题解:考场上只会2^m*n的递推,简直sb。。。MLE+TLE

             因为昨天刚做了一道类似的T_T

             话说暴力枚举每个位置上的数也比这个快把T_T

             然后搬运一份正解:

             (用meet-in-the-middle的思想。先一遍dfs暴力求出长度为[n/2]的情况下([x]表示对x下取整),某一hash值f有多少个串与之对应。

             求出33对于2^m的逆元inv,然后反向dfs后半段。可以秒出。)

             竟如此简单。。。 话说在黑书上看过这种思想啊,当时为什么没想出来T_T

             有几个细节需注意:

             1)因为gcd(33,1<<m)==1,所以33对1<<m有逆元

             2)33模1<<m的逆元=power(33,phi(1<<m)-1)=power(33,(1<<(m-1))-1)

             3)因为 a xor b xor b=a,所以反向搜的时候直接异或就可以,这应该是此题的特殊之处吧,

    代码:(考场上暴力DP)

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 1050000
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,ll>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 ll n,k,m,sum,cnt,mx,f[11][maxn];
    32 int main()
    33 {
    34     freopen("input.txt","r",stdin);
    35     freopen("output.txt","w",stdout);
    36     n=read();k=read();m=read();
    37     f[0][0]=1;sum=1;mx=1<<m;
    38     for1(i,n)
    39     {
    40         cnt=0;
    41         for0(j,mx-1)
    42          if(f[i-1][j])
    43           {
    44               cnt++;
    45               for1(k,26)
    46                f[i][((j*33)^k)%mx]+=f[i-1][j];
    47               if(cnt==sum)break; 
    48           }
    49         sum*=26;
    50     }
    51     cout<<f[n][k]<<endl;
    52     return 0;
    53 }
    View Code

    代码:(正解)

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 500+100
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define mod 1000000007
    23 using namespace std;
    24 inline ll read()
    25 {
    26     ll x=0,f=1;char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 ll n,k,m,inv,res,mx1,mx2,sum[1<<25];
    32 inline void dfs(int dep,ll s)
    33 {
    34     if(dep==mx1)sum[s%m]++;
    35     else for1(i,26)dfs(dep+1,((s<<5)+s^i)%m);
    36 }
    37 inline void dfs2(int dep,ll s)
    38 {
    39     if(dep==mx2)res+=sum[s%m];
    40 
    41     else for1(i,26)dfs2(dep+1,((s^i)*inv)%m);
    42 }
    43 inline ll power(ll x,ll y)
    44 {
    45     ll t=1;
    46     for(;y;y>>=1,x=(x*x)%m)
    47      if(y&1)t=(t*x)%m;
    48     return t;
    49 }
    50 int main()
    51 {
    52     freopen("input.txt","r",stdin);
    53     freopen("output.txt","w",stdout);
    54     n=read();k=read();m=1<<read();inv=power(33,(m>>1)-1);
    55     mx1=(n+1)>>1;mx2=n>>1;dfs(0,0);dfs2(0,k);
    56     cout<<res<<endl;
    57     return 0;
    58 }
    View Code

     以后一定要多动脑想一想,不要误以为t2这种sb题不可做!!!

  • 相关阅读:
    【设计模式】6.模板方法模式
    【设计模式】5.原型模式
    【设计模式】4.工厂模式
    【设计模式】3.代理模式
    zookeeper集群的搭建
    zookeeper实现分布式锁的原理和一个小例子
    zookeeper配置管理实现原理----监听事件watch
    zookeeper的javaAPI操作(基于Curator的CRUD)
    java.lang.IllegalArgumentException: A HostProvider may not be empty!
    Zookeeper的安装和基本操作
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4007957.html
Copyright © 2011-2022 走看看