T1旋转子段
一开始脑袋抽了花了近一个小时写了个跟这题毫无关系的莫名其妙的代码,一急代码就各种bug,最后t1就花了一个半小时多,然后后面时间不太够了,考得稀烂。
因为每个数存在唯一的中心使得绕这个中心翻转后成为”不动点“,容易想到枚举对称中心。因为把关于这个中心对称的所有点都翻转不一定最优(然而王巨直接全翻过了,数据大概是用脚造的),那么按到对称中心的距离排序后一一枚举翻到哪个位置的答案,不翻的部分用前缀和数组维护即可,每个点只会在它的对称中心被枚举到,所以复杂度是nlogn(set or 排序)的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 */
T2跳房子
这是一个很sb的dijkstra,但是机房大多数人(除了yicongli)都没考虑清楚,总是在同一个地方打两次传送门来传送,会被这样的数据卡掉
#####
#...#
#...#
#.C.#
#...#
#...#
#.F.#
#####
题解说的是,先跑一遍dijkstra找到每个点最近的墙,我看到这个数据的时候也是这样想的,但是ycl吊打标解。
如图,从一个点到离它最近的墙和它要去的目标点的交点的路径上是一定没有墙的,否则就不是最近的墙了,所以一定可以直接走到那个交点,然后从交点打出两个传送门进行传送,所以把每个点向它四周能到达的第一个墙连距离为四个距离的最小值的边就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 */
T3column
我的树状数组还是当年ppz教的,一直不是很会搞树状数组,知道标解但是树状数组半天弄不陈展,然后最后放弃了直接打了个暴力,下来后想着要写树状数组还是头疼,就写了线段树,于是很快就过了。。
枚举每个点i作为最高点,然后二分高度,如果此时aj<hj的多于aj>hj的就r--否则l++
aj和hj的关系,对于i左边的点看 hi+(i-j)-aj正负,右边看hi+(j-i)-aj的正负,展开之后用数据结构维护就好了。
因为树状数组的时候我总是搞不清楚查的上下界什么的,写线段树的时候虽然写得比较丑,但是直接传进v让它去帮我找小于v或大于v的东西,这样我自己就很容易理清楚
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 */