【HDOJ6586】String(枚举)
题意:给定一个由小写字母组成的字符串S,要求从中选出一个长度为k的子序列,使得其字典序最小,并且第i个字母在子序列中出现的次数在[l[i],r[i]]之间
n,k<=1e5
思路:大概就是记一下后缀和然后逐位确定,把能想到的界都给卡上
这种题写错的话大概随机数据拍都能拍出来,就是调起来占大量机时并且体感极差就是了
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,int>P; 11 #define N 110000 12 #define M 151000 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pi acos(-1) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 20 #define lowbit(x) x&(-x) 21 #define Rand (rand()*(1<<16)+rand()) 22 #define id(x) ((x)<=B?(x):m-n/(x)+1) 23 #define ls p<<1 24 #define rs p<<1|1 25 26 const ll MOD=1e9+7,inv2=(MOD+1)/2; 27 double eps=1e-6; 28 ll INF=1e18; 29 ll inf=5e13; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 int s[N][26],nxt[N][26],ans[N],l[N],r[N],t[26],a[26],n,K; 34 char ch[N]; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 int isok(int x,int y,int z) 46 { 47 int t=nxt[x][z]; 48 //printf("x=%d y=%d z=%d t=%d\n",x,y,z,t); 49 if(t==n+1) return 0; 50 //if(K-y>n-t) return 0; 51 if(a[z]+1>r[z]) return 0; 52 a[z]++; 53 //rep(i,0,3) printf("%d ",a[i]); 54 //printf("\n"); 55 int tmp=0; 56 rep(i,0,25) tmp+=min(s[t+1][i],r[i]-a[i]); 57 //printf("tmp1=%d\n",tmp); 58 if(tmp<K-y) 59 { 60 a[z]--; 61 return 0; 62 } 63 64 rep(i,0,25) 65 if(a[i]+min(s[t+1][i],min(n-t,K-y))<l[i]) 66 { 67 a[z]--; 68 return 0; 69 } 70 71 tmp=0; 72 rep(i,0,25) tmp+=max(0,l[i]-a[i]); 73 //printf("tmp2=%d\n",tmp); 74 if(tmp>n-t||tmp>K-y) 75 { 76 a[z]--; 77 return 0; 78 } 79 a[z]--; 80 return 1; 81 } 82 83 int main() 84 { 85 //freopen("1.in","r",stdin); 86 //freopen("1.out","w",stdout); 87 while(scanf("%s",ch+1)!=EOF) 88 { 89 n=strlen(ch+1),K=read(); 90 if(K==0) break; 91 rep(i,0,25) t[i]=n+1; 92 rep(i,0,25) s[n+1][i]=0; 93 per(i,n,0) 94 { 95 int x=0; 96 if(i) x=ch[i]-'a'; 97 rep(j,0,25) nxt[i][j]=t[j]; 98 t[x]=i; 99 rep(j,0,25) s[i][j]=s[i+1][j]; 100 s[i][x]++; 101 } 102 rep(i,0,25) l[i]=read(),r[i]=read(); 103 int flag=1; 104 rep(i,1,K) ans[i]=0; 105 rep(i,0,25) a[i]=0; 106 int now=0; 107 rep(i,1,K) 108 { 109 int k=26; 110 rep(j,0,25) 111 if(isok(now,i,j)){k=j; now=nxt[now][j]; a[j]++; break;} 112 113 if(k==26){flag=0; break;} 114 ans[i]=k; 115 //printf("ans%d=%d now=%d\n",i,k,now); 116 } 117 //printf("flag=%d\n",flag); 118 if(flag) 119 { 120 rep(i,1,K) printf("%c",ans[i]+'a'); 121 printf("\n"); 122 } 123 else printf("-1\n"); 124 } 125 126 return 0; 127 }
null