这套月赛题不是特别难
T1:离散化+单调队列,队列里出现数的种类不超过K+1,找最大的num[a[i]]
T2:一眼可以看出BFS+状压DP,还要SPFA预处理出各个块之间的dis
T3:线段树,没什么难度
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 100010; 6 int n,K,a[maxn],b[maxn],m,ans,head,tail,q[maxn],vis[maxn],cnt; 7 int main(){ 8 scanf("%d%d", &n, &K); 9 for (int i=1; i<=n; i++) scanf("%d", &b[i]),a[i]=b[i]; 10 sort(b+1,b+1+n); 11 m=unique(b+1,b+1+n)-b-1; 12 for (int i=1; i<=n; i++) a[i]=lower_bound(b+1,b+1+m,a[i])-b; 13 //for (int i=1; i<=n; i++) printf("%d ", a[i]); 14 head=tail=cnt=0; 15 for (int i=1; i<=n; i++){ 16 if (!vis[a[i]]) cnt++; 17 vis[a[i]]++; q[tail++]=i; 18 while (head<tail && cnt>K+1){ 19 vis[a[q[head]]]--; if (vis[a[q[head]]]==0) cnt--; 20 head++; 21 } 22 ans=max(ans,vis[a[q[tail-1]]]); 23 } 24 printf("%d ", ans); 25 return 0; 26 }
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<queue> 5 using namespace std; 6 const int maxn = 52; 7 const int dx[4]={0,0,1,-1}; 8 const int dy[4]={1,-1,0,0}; 9 struct node{ 10 int x,y; 11 node(int _x, int _y):x(_x),y(_y){} 12 }; 13 int n,m,d[maxn][maxn],f[1<<15][16],dis[16][16],id[maxn][maxn],vis[maxn][maxn],cnt,stx[16],sty[16],N; 14 char s[maxn][maxn]; 15 16 bool check(int x, int y){ 17 if (x<1 || y<1 || x>n || y>m) return 0; return 1; 18 } 19 20 void bfs(int sx, int sy, int num){ 21 queue<node> Q; 22 Q.push(node(sx,sy)); id[sx][sy]=num; 23 vis[sx][sy]=1; 24 while (!Q.empty()){ 25 int x=Q.front().x, y=Q.front().y; Q.pop(); 26 for (int k=0; k<4; k++){ 27 int tx=x+dx[k], ty=y+dy[k]; 28 if (check(tx,ty) && !vis[tx][ty] && s[tx][ty]=='X'){ 29 vis[tx][ty]=1; id[tx][ty]=num; 30 Q.push(node(tx,ty)); 31 } 32 } 33 } 34 } 35 36 void find_land(){ 37 cnt=0; 38 for (int i=1; i<=n; i++) 39 for (int j=1; j<=m; j++) 40 if (s[i][j]=='X' && !vis[i][j]){ 41 bfs(i,j,++cnt); 42 stx[cnt]=i; sty[cnt]=j; 43 } 44 // for (int i=1; i<=cnt; i++) printf(" %d %d ", stx[i], sty[i]); 45 } 46 47 void spfa(int sx, int sy, int num){ 48 queue<node> Q; 49 int next,cost; memset(d,0x3f,sizeof(d)); 50 memset(dis[num],0x3f,sizeof(dis[num])); 51 Q.push(node(sx,sy)); d[sx][sy]=0; vis[sx][sy]=2; dis[num][num]=0; 52 while (!Q.empty()){ 53 int x=Q.front().x, y=Q.front().y; Q.pop(); 54 for (int k=0; k<4; k++){ 55 int tx=x+dx[k], ty=y+dy[k]; 56 if (!check(tx,ty) || s[tx][ty]=='.') continue; 57 cost=(s[tx][ty]=='S'); 58 if (d[tx][ty]>d[x][y]+cost){ 59 d[tx][ty]=d[x][y]+cost; 60 if (vis[tx][ty]!=2){ 61 vis[tx][ty]=2; 62 Q.push(node(tx,ty)); 63 } 64 } 65 if ((s[tx][ty]=='X') && ((next=id[tx][ty])!=num)) dis[num][next]=min(dis[num][next],d[tx][ty]); 66 } 67 vis[x][y]=1; 68 } 69 } 70 71 void dp(){ 72 N=(1<<cnt); 73 memset(f,0x3f,sizeof(f)); 74 for (int i=1; i<=cnt; i++) f[(1<<(i-1))][i]=0; 75 for (int s=1; s<N; s++){ 76 for (int i=1; i<=cnt; i++) if (s&(1<<(i-1))) 77 for (int j=1; j<=cnt; j++) if (!(s&(1<<(j-1)))) 78 f[s^(1<<(j-1))][j]=min(f[s^(1<<(j-1))][j],f[s][i]+dis[i][j]); 79 } 80 int ans=0x7fffffff; 81 for (int i=1; i<=cnt; i++) ans=min(ans,f[N-1][i]); 82 printf("%d ", ans); 83 } 84 85 int main(){ 86 scanf("%d%d", &n, &m); 87 for (int i=1; i<=n; i++){ 88 scanf("%s", s[i]+1); 89 } 90 find_land(); 91 for (int i=1; i<=cnt; i++) 92 spfa(stx[i],sty[i],i); 93 dp(); 94 return 0; 95 }
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn = 500010; 6 struct node{ 7 int l,r,len,lz,lm,rm,mx; 8 }t[maxn*4],now; 9 int n,m,x,y,ans; 10 char opt[3]; 11 12 void pushup(int x){ 13 t[x].lm=t[x<<1].lm; 14 if (t[x<<1].lm==t[x<<1].len) t[x].lm=t[x<<1].len+t[x<<1|1].lm; 15 t[x].rm=t[x<<1|1].rm; 16 if (t[x<<1|1].rm==t[x<<1|1].len) t[x].rm=t[x<<1|1].len+t[x<<1].rm; 17 t[x].mx=max(t[x<<1].rm+t[x<<1|1].lm,max(t[x<<1].mx,t[x<<1|1].mx)); 18 } 19 20 void pushdown(int x){ 21 if (t[x].lz==1){ //涂色 22 t[x<<1].lz=1; t[x<<1|1].lz=1; 23 t[x<<1].lm=t[x<<1].rm=t[x<<1].mx=0; 24 t[x<<1|1].lm=t[x<<1|1].rm=t[x<<1|1].mx=0; 25 } 26 if (t[x].lz==2){ //不涂色 27 t[x<<1].lz=2; t[x<<1|1].lz=2; 28 t[x<<1].lm=t[x<<1].rm=t[x<<1].mx=t[x<<1].len; 29 t[x<<1|1].lm=t[x<<1|1].rm=t[x<<1|1].mx=t[x<<1|1].len; 30 } 31 t[x].lz=0; 32 } 33 34 node query(int x, int p){ 35 int l=t[x].l, r=t[x].r; 36 pushdown(x); 37 if (t[x<<1].mx>=p) return query(x<<1,p); 38 else if (t[x<<1].rm+t[x<<1|1].lm>=p){ 39 node ret; 40 ret.l=t[x<<1].r-t[x<<1].rm+1; 41 ret.r=ret.l+p-1; 42 return ret; 43 }else return query(x<<1|1,p); 44 } 45 46 void update(int a, int b, int x, int c){ 47 int l=t[x].l, r=t[x].r; 48 if (l==a && r==b){ 49 if (c==1){ 50 t[x].lz=1; 51 t[x].lm=t[x].rm=t[x].mx=0; 52 } 53 if (c==0){ 54 t[x].lz=2; 55 t[x].lm=t[x].rm=t[x].mx=t[x].len; 56 } 57 return; 58 } 59 int mid=l+r>>1; 60 pushdown(x); 61 if (b<=mid) update(a,b,x<<1,c); 62 else if (a>mid) update(a,b,x<<1|1,c); 63 else update(a,mid,x<<1,c),update(mid+1,b,x<<1|1,c); 64 pushup(x); 65 } 66 67 void build(int l, int r, int x){ 68 t[x].l=l; t[x].r=r; t[x].len=r-l+1; 69 if (l==r){ 70 t[x].lz=0; t[x].lm=t[x].rm=t[x].mx=1; 71 return; 72 } 73 int mid=l+r>>1; 74 build(l,mid,x<<1); 75 build(mid+1,r,x<<1|1); 76 pushup(x); 77 } 78 79 int main(){ 80 scanf("%d%d", &n, &m); 81 build(1,n,1); 82 //printf("%d ", t[1].mx); 83 while (m--){ 84 scanf("%s", opt); 85 if (opt[0]=='A'){ 86 scanf("%d", &x); 87 if (t[1].mx<x) ans++; 88 else{ 89 now=query(1,x); 90 //printf(" %d %d ", now.l, now.r); 91 update(now.l,now.r,1,1); 92 } 93 }else{ 94 scanf("%d%d", &x, &y); 95 update(x,y,1,0); 96 } 97 } 98 printf("%d ", ans); 99 return 0; 100 }