• NOIp2018集训test-9-16(联考二day2)


    T1旋转子段

    一开始脑袋抽了花了近一个小时写了个跟这题毫无关系的莫名其妙的代码,一急代码就各种bug,最后t1就花了一个半小时多,然后后面时间不太够了,考得稀烂。

    因为每个数存在唯一的中心使得绕这个中心翻转后成为”不动点“,容易想到枚举对称中心。因为把关于这个中心对称的所有点都翻转不一定最优(然而王巨直接全翻过了,数据大概是用脚造的),那么按到对称中心的距离排序后一一枚举翻到哪个位置的答案,不翻的部分用前缀和数组维护即可,每个点只会在它的对称中心被枚举到,所以复杂度是nlogn(set or 排序)的。

     1 //Achen
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<queue>
     9 #include<cmath>
    10 #include<set>
    11 #include<map>
    12 #define Formylove return 0
    13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
    14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    15 const int N=1000007;
    16 typedef long long LL;
    17 typedef double db;
    18 using namespace std;
    19 int n,a[N],sa[N],sum[N],f[N],ans;
    20 
    21 template<typename T>void read(T &x)  {
    22     char ch=getchar(); x=0; T f=1;
    23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    24     if(ch=='-') f=-1,ch=getchar();
    25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    26 }
    27 
    28 struct node {
    29     int i,ai;
    30     node(int i,int ai):i(i),ai(ai){}
    31     friend bool operator <(const node&A,const node&B) {
    32         return max(A.i,A.ai)<max(B.i,B.ai);
    33     }
    34 };
    35 multiset<node>vc[N];
    36 
    37 #define ANS
    38 int main() {
    39 #ifdef ANS
    40     freopen("rotate.in","r",stdin);
    41     freopen("rotate.out","w",stdout);
    42 #endif
    43     read(n);
    44     For(i,1,n) {
    45         read(a[i]);
    46         sa[a[i]]=i;
    47         sum[i]=sum[i-1]+(a[i]==i);
    48         vc[i+a[i]].insert(node(i,a[i]));
    49     }
    50     For(i,1,n) {
    51         int r=max(i,a[i]),l=min(i,a[i]);
    52         f[i]=sum[l-1];
    53     }
    54     For(i,1,2*n) if(vc[i].size()) {
    55         int tp=0;
    56         while(vc[i].size()){
    57             node x=*vc[i].begin();
    58             vc[i].erase(vc[i].begin());
    59             tp++;
    60             ans=max(ans,f[x.i]+tp+sum[n]-sum[max(x.i,x.ai)]);
    61         }
    62     }
    63     printf("%d
    ",ans);
    64     Formylove;
    65 }
    66 /*
    67 20
    68 12 2 6 16 3 17 19 15 13 4 11 20 8 10 18 1 9 5 7 14
    69 */
    View Code

     

    T2跳房子

    这是一个很sb的dijkstra,但是机房大多数人(除了yicongli)都没考虑清楚,总是在同一个地方打两次传送门来传送,会被这样的数据卡掉

    #####
    #...#
    #...#
    #.C.#
    #...#
    #...#
    #.F.#
    #####

    题解说的是,先跑一遍dijkstra找到每个点最近的墙,我看到这个数据的时候也是这样想的,但是ycl吊打标解。

    如图,从一个点到离它最近的墙和它要去的目标点的交点的路径上是一定没有墙的,否则就不是最近的墙了,所以一定可以直接走到那个交点,然后从交点打出两个传送门进行传送,所以把每个点向它四周能到达的第一个墙连距离为四个距离的最小值的边就可以了。

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #include<map>
     12 #define Formylove return 0
     13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     15 const int N=507;
     16 typedef long long LL;
     17 typedef double db;
     18 using namespace std;
     19 int n,m,sx,sy,tx,ty,xx[4]={0,0,-1,1},yy[4]={-1,1,0,0}; 
     20 char s[N][N];
     21  
     22 
     23 template<typename T>void read(T &x)  {
     24     char ch=getchar(); x=0; T f=1;
     25     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     26     if(ch=='-') f=-1,ch=getchar();
     27     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     28 }
     29 
     30 struct node {
     31     int x,y,dis;
     32     node(int x,int y,int dis):x(x),y(y),dis(dis){}
     33     friend bool operator <(const node&A,const node&B) {
     34         return A.dis>B.dis;
     35     }
     36 };
     37 
     38 int ok(int x,int y) { return x>=1&&x<=n&&y>=1&&y<=m; }
     39 
     40 #define pr pair<int,int>
     41 #define fi first
     42 #define se second
     43 pr tt[N][N][4];
     44 int td[N][N];
     45 void pre() {
     46     memset(td,127/3,sizeof(td));
     47     For(i,1,n) {
     48         For(j,1,m) {
     49             if(s[i][j]!='#'&&s[i][j-1]!='#') {
     50                 tt[i][j][0].fi=tt[i][j-1][0].fi;
     51                 tt[i][j][0].se=tt[i][j-1][0].se;    
     52             }
     53             else tt[i][j][0].fi=i,tt[i][j][0].se=j;
     54             td[i][j]=min(td[i][j],j-tt[i][j][0].se);
     55         }
     56         Rep(j,m,1) {
     57             if(s[i][j]!='#'&&s[i][j+1]!='#') {
     58                 tt[i][j][1].fi=tt[i][j+1][1].fi;
     59                 tt[i][j][1].se=tt[i][j+1][1].se;    
     60             }
     61             else tt[i][j][1].fi=i,tt[i][j][1].se=j;
     62             td[i][j]=min(td[i][j],tt[i][j][1].se-j);
     63         }
     64     }
     65     For(j,1,m) {
     66         For(i,1,n) {
     67             if(s[i][j]!='#'&&s[i-1][j]!='#') {
     68                 tt[i][j][2].fi=tt[i-1][j][2].fi;
     69                 tt[i][j][2].se=tt[i-1][j][2].se;    
     70             }
     71             else tt[i][j][2].fi=i,tt[i][j][2].se=j;
     72             td[i][j]=min(td[i][j],i-tt[i][j][2].fi);
     73         }
     74         Rep(i,n,1) {
     75             if(s[i][j]!='#'&&s[i+1][j]!='#') {
     76                 tt[i][j][3].fi=tt[i+1][j][3].fi;
     77                 tt[i][j][3].se=tt[i+1][j][3].se;    
     78             }
     79             else tt[i][j][3].fi=i,tt[i][j][3].se=j;
     80             td[i][j]=min(td[i][j],tt[i][j][3].fi-i);
     81         }
     82     }
     83 }
     84 
     85 int dis[N][N],vis[N][N];
     86 priority_queue<node>que;
     87 void dijkstra() {
     88     que.push(node(sx,sy,0));
     89     while(!que.empty()) {
     90         node tp=que.top();
     91         que.pop();
     92         if(dis[tp.x][tp.y]!=tp.dis||vis[tp.x][tp.y]) continue;
     93         vis[tp.x][tp.y]=1;
     94         For(i,0,3) {
     95             int nx=tp.x+xx[i],ny=tp.y+yy[i];
     96             if(ok(nx,ny)&&s[nx][ny]!='#') {
     97                 if(dis[nx][ny]>tp.dis+1) {
     98                     dis[nx][ny]=tp.dis+1;
     99                     que.push(node(nx,ny,tp.dis+1));
    100                 }
    101             }
    102             pr t=tt[tp.x][tp.y][i];
    103             if(t.fi==tp.x&&t.se==tp.y) continue;
    104             if(dis[t.fi][t.se]>tp.dis+1+td[tp.x][tp.y]) {
    105                 dis[t.fi][t.se]=tp.dis+1+td[tp.x][tp.y];
    106                 que.push(node(t.fi,t.se,tp.dis+1+td[tp.x][tp.y])); 
    107             }
    108         }
    109     }
    110 }
    111 
    112 #define ANS
    113 int main() {
    114 #ifdef ANS
    115     freopen("cell.in","r",stdin);
    116     freopen("cell.out","w",stdout);
    117 #endif
    118     read(n); read(m);
    119     For(i,1,n) {
    120         scanf("%s",s[i]+1);
    121         For(j,1,m) {
    122             if(s[i][j]=='C') sx=i,sy=j;
    123             else if(s[i][j]=='F') tx=i,ty=j;
    124         }
    125     }
    126     pre();
    127     memset(dis,127/3,sizeof(dis));
    128     int inf=dis[0][0];
    129     dis[sx][sy]=0;
    130     dijkstra();
    131     if(dis[tx][ty]==inf) puts("no");
    132     else printf("%d
    ",dis[tx][ty]); 
    133     Formylove;
    134 }
    135 /*
    136 4 5
    137 #####
    138 #C#.#
    139 ###F#
    140 #####
    141 */
    View Code

    T3column

    我的树状数组还是当年ppz教的,一直不是很会搞树状数组,知道标解但是树状数组半天弄不陈展,然后最后放弃了直接打了个暴力,下来后想着要写树状数组还是头疼,就写了线段树,于是很快就过了。。

    枚举每个点i作为最高点,然后二分高度,如果此时aj<hj的多于aj>hj的就r--否则l++

    aj和hj的关系,对于i左边的点看 hi+(i-j)-aj正负,右边看hi+(j-i)-aj的正负,展开之后用数据结构维护就好了。

    因为树状数组的时候我总是搞不清楚查的上下界什么的,写线段树的时候虽然写得比较丑,但是直接传进v让它去帮我找小于v或大于v的东西,这样我自己就很容易理清楚

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #include<map>
     12 #define Formylove return 0
     13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     15 const int N=200007;
     16 typedef long long LL;
     17 typedef double db;
     18 using namespace std;
     19 int n,a[N],b[N],sz,a1[N],a2[N];
     20 LL ans=1e18;
     21 
     22 template<typename T>void read(T &x)  {
     23     char ch=getchar(); x=0; T f=1;
     24     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     25     if(ch=='-') f=-1,ch=getchar();
     26     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     27 }
     28 
     29 #define pr pair<int,LL>
     30 #define fi first
     31 #define se second
     32 #define lc (x<<1)
     33 #define rc ((x<<1)|1)
     34 #define mid ((l+r)>>1)
     35 
     36 struct sgtree{
     37     pr sg[N<<2];
     38     void update(int x,int l,int r,int pos,int f) {
     39         if(l==r) {
     40             sg[x].fi+=f;
     41             sg[x].se+=b[l]*f; 
     42             return;
     43         }
     44         if(pos<=mid) update(lc,l,mid,pos,f);
     45         else update(rc,mid+1,r,pos,f);
     46         sg[x].fi=sg[lc].fi+sg[rc].fi;
     47         sg[x].se=sg[lc].se+sg[rc].se;
     48     }
     49 
     50     pr qryx(int x,int l,int r,int v) {
     51         if(b[r]<v) return sg[x];
     52         if(b[l]>=v) return make_pair(0,0);
     53         pr rs,tp; 
     54         if(b[mid]>=v) return qryx(lc,l,mid,v);
     55         rs=sg[lc];
     56         tp=qryx(rc,mid+1,r,v);
     57         rs.fi+=tp.fi,rs.se+=tp.se;
     58         return rs;
     59     }
     60 
     61     pr qryd(int x,int l,int r,int v) {
     62         if(b[l]>v) return sg[x];
     63         if(b[r]<=v) return make_pair(0,0);
     64         pr rs,tp;
     65         if(b[mid]<=v) return qryd(rc,mid+1,r,v);
     66         rs=sg[rc];
     67         tp=qryd(lc,l,mid,v);
     68         rs.fi+=tp.fi,rs.se+=tp.se;
     69         return rs;
     70     }
     71 }t1,t2;
     72 
     73 void solve() {
     74     For(i,1,n) {
     75         b[++b[0]]=i+a[i];
     76         b[++b[0]]=i-a[i];
     77     }
     78     sort(b+1,b+b[0]+1);
     79     sz=unique(b+1,b+b[0]+1)-(b+1);
     80     For(i,1,n) {
     81         a1[i]=lower_bound(b+1,b+sz+1,i+a[i])-b;
     82         a2[i]=lower_bound(b+1,b+sz+1,i-a[i])-b;
     83         t1.update(1,1,sz,a1[i],1);
     84     }
     85     For(i,1,n) {
     86         t1.update(1,1,sz,a1[i],-1);
     87         int l=max(i,n-i+1),r=1e9+n,rs=0;
     88         while(l<=r) {
     89             pr tp1=t2.qryd(1,1,sz,i-mid);
     90             pr tp2=t2.qryx(1,1,sz,i-mid);
     91             pr tp3=t1.qryx(1,1,sz,mid+i);
     92             pr tp4=t1.qryd(1,1,sz,mid+i);
     93             LL tpans=((LL)tp1.fi*(mid-i)+tp1.se)-((LL)tp2.fi*(mid-i)+tp2.se)+
     94             ((LL)tp3.fi*(mid+i)-tp3.se)-((LL)tp4.fi*(mid+i)-tp4.se)+abs(mid-a[i]);
     95             ans=min(ans,tpans);
     96             if(tp1.fi+tp3.fi>tp2.fi+tp4.fi) r=mid-1;
     97             else l=mid+1;
     98         }
     99         t2.update(1,1,sz,a2[i],1); 
    100     }
    101 }
    102 
    103 #define ANS
    104 int main() {
    105 #ifdef ANS
    106     freopen("column.in","r",stdin);
    107     freopen("column.out","w",stdout);
    108 #endif
    109     read(n);
    110     For(i,1,n) read(a[i]);
    111     solve();
    112     printf("%lld
    ",ans);
    113     Formylove;
    114 }
    115 /*
    116 4
    117 1 1 2 3
    118 */
    View Code
  • 相关阅读:
    德国10马克,高斯正态分布函数
    安装python的第三方库 geopandas
    Python版本的GDAL 安装
    [原创]App崩溃率统计工具推荐
    用户增长模型AARRR模型
    [原创]nginx日志分析工具
    [原创]浅谈移动互联网创业公司工具类产品
    [原创]浅谈在创业公司对PMF的理解
    [原创]浅谈创业公司如何选择产品方向
    [原创]浅谈在创业公司对MVP的理解
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9671234.html
Copyright © 2020-2023  润新知