提交地址
1002 Boring String Problem
后缀数组+RMQ+二分
后缀数组二分确定第K不同子串的位置 , 二分LCP确定可选的区间范围 , RMQ求范围内最小的sa
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define prt(k) cout<<#k" = "<<k<<endl; const int N = 100010; int sa[N], rank[N], rank2[N], h[N],c[N], *x, *y, ans[N]; typedef long long ll; char str[N]; bool cmp(int* r, int a, int b, int l, int n) { return r[a]==r[b] && a+l<n && b+l<n && r[a+l]==r[b+l]; } void radix_sort(int n,int sz) { for(int i=0; i<sz; i++) c[i]=0; for(int i=0; i<n; i++) c[x[y[i]]]++; for(int i=1; i<sz; i++) c[i]+=c[i-1]; for(int i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i]; } void get_sa(char c[],int n,int sz=128) { x=rank,y=rank2; for(int i=0;i<n;i++) x[i]=c[i],y[i]=i; radix_sort(n,sz); for(int len=1;len<n;len<<=1) { int yid=0; for(int i=n-len;i<n;i++) y[yid++]=i; for(int i=0;i<n;i++) if(sa[i]>=len) y[yid++]=sa[i]-len; radix_sort(n,sz); swap(x,y); x[sa[0]]=yid=0; for(int i=1;i<n;i++) { x[sa[i]]=cmp(y,sa[i],sa[i-1],len,n) ? yid : ++yid; } sz=yid+1; if(sz>=n) break; } for(int i=0;i<n;i++) rank[i]=x[i]; } void get_h(char str[],int n) { int k=0; h[0]=0x3f3f3f3f; for(int i=0;i<n;i++) { if(rank[i]==0) continue; k=max(k-1,0); int j=sa[rank[i]-1]; while(i+k<n && j+k<n && str[i+k]==str[j+k]) k++; h[rank[i]]=k; } } int dp[N][20]; int mmm[N][22]; void RMQ_init(int n) { for(int i=0;i<n;i++) dp[i][0]=h[i], mmm[i][0]=sa[i]; dp[0][0]=0x3f3f3f3f; for(int i=1;(1<<i)<=n;i++) { for(int j=0;j+(1<<i)-1<n; j++) dp[j][i]=min(dp[j][i-1], dp[j+(1<<(i-1))][i-1]), mmm[j][i]=min(mmm[j][i-1], mmm[j+(1<<(i-1))][i-1]); } } int LCP(int l,int r,int n) { if(l==r) return n-sa[l]; l++; if(l>r) swap(l,r); int k = 0; while(1<<(k+1) <= r-l+1) k++; return min(dp[l][k],dp[r-(1<<k)+1][k]); } ll Range[N]; int bin(ll x, int n) { int ans = -1; int l=0, r=n-1, mid; while(l<=r) { mid=(l+r)/2; if(Range[mid]<x) ans=mid,l=mid+1; else r=mid-1; } return ans; } int MMM(int l, int r) { if(l>r) swap(l,r); int k = 0; while(1<<(k+1) <= r-l+1) k++; return min(mmm[l][k], mmm[r-(1<<k)+1][k]); } int binID(int x,int n,int len) { int ans=x; int l=x,r=n-1,mid; while(l<=r) { mid=(l+r)/2; if(LCP(x,mid,n)>=len) { ans=mid; l=mid+1; } else r=mid-1; } return ans; } int main() { while(scanf("%s",str)==1) { int n=strlen(str); get_sa(str,n); get_h(str,n); RMQ_init(n); h[0]=0; for(int i=0;i<n;i++) { Range[i] = (n-sa[i])-h[i]; if(i-1>=0) Range[i]+=Range[i-1]; } int q; cin>>q; int L=0,R=0; while(q--) { ll V; scanf("%I64d",&V); ll K = (L^R^V) + 1; if(K>Range[n-1]) { L=0, R=0; printf("0 0\n"); continue; } int id = bin(K,n); ll jian=0; if(id>=0) jian=Range[id]; ll res=K-jian; id++; int len=h[id]+res; int hid=binID(id,n,len); int Left=MMM(id,hid); L=Left+1, R=Left+len; printf("%d %d\n",L,R); } } }
1003 Paint Pearls
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define prt(k) cout<<#k" = "<<k<<endl; const int N = 50010; #include<map> #include<algorithm> int a[N]; int n; int dp[N]; int b[N]; int fa[N]; int f(int x) { return x==fa[x]?x:fa[x]=f(fa[x]); } void U(int x, int y) { x=f(x),y=f(y); if(x-y) fa[y]=x; } int sqr(int x) { return x * x; } int last[N]; int main() { while(scanf("%d",&n)==1) { for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n; i++) b[i] = a[i]; map<int,int> mp; sort(b+1, b+n+1); int m = unique(b+1, b+n+1) - (b+1); for(int i=1;i<=m;i++) mp[b[i]] = i ; for(int i = 1; i<=n; i++) a[i] = mp[a[i]] ,fa[i]=i, last[i]=-1; dp[0] = 0; map<int,int> tmp; for(int i = 1; i <= n; i++) { if(~last[a[i]]) U(last[a[i]]-1, last[a[i]]); last[a[i]] = i; dp[i] = i; int c = 0; for(int j = i; j>0 ; j=f(j-1)) { c++; if( c*c > dp[i]) break; dp[i] = min(dp[i], dp[f(j-1)] + c*c ); } } cout<<dp[n]<<endl; } }
1009 233 Matrix
首先A[0][n] = A[0][n - 1] * 10 + 3
然后A[m] [n] = A[m] [n - 1] + A[m - 1][n - 1] + ... + A[1][n - 1] + A[0][n]
然后A[m] [n] = A[m] [n - 1] + A[m - 1][n - 1] + ... + A[1][n - 1] + (A[0][n - 1] * 10 + 3)
然后A[m] [n] = 3 + 10 * A[0][n - 1] +A[1] [n - 1] + A[2][n - 1] + ... + A[m - 1][n - 1] + A[m][n - 1]
就能看出,A[*][n] 是A[*][n - 1]的线性表示了。
233 Matrix#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; #include<vector> typedef long long ll; #define prt(k) cout<< #k" = " << k<< " \n"; /// const ll mod = 10000007; int n,m; void add(ll &a, ll b) { a=(a+b)%mod; } struct Matrix { ll a[22][22]; Matrix() { memset(a,0,sizeof a); } Matrix operator*(Matrix b) { Matrix c; for(int i = 0; i < n; i++) for(int j =0; j<n; j++) { c.a[i][j]= 0; for(int k = 0; k < n; k ++) add(c.a[i][j], a[i][k] * b.a[k][j] % mod); } return c; } void out() { for(int i =0; i<n; i++) { for(int j = 0 ; j < n; j++) cout<<a[i][j]<<' '; cout << endl; } } }; Matrix pow(Matrix a, int m) { Matrix res; int i,j; for(i = 0; i < ::n; i++) for(j = 0; j < ::n; j++) res.a[i][j] = (i == j); for(; m>0; m>>=1, a=a*a) if(m&1) res = res * a; return res; } int main() { while(cin >> n >> m) { n += 2; int a[22]; a[0] = 3; a[1] = 23; for(int i = 2; i < n; i ++) cin>>a[i]; Matrix ma; for(int i = 0 ; i < n; i++) { int j; for( j = 0 ; j<=i; j++) if(j == 1) ma.a[i][j] = 10; else ma.a[i][j] = 1; for(; j<n; j++) ma.a[i][j] = 0; } ; ma = pow(ma, m); ll ans= 0; // cout<<ma.a[0][0]; for(int i = 0; i<n; i++) add(ans, ma.a[n-1][i] * a[i] % mod); cout << ans << endl; } } |
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define prt(k) cout<<#k" = "<<k<<endl; const double eps = 1e-8; int dx[]={0,0,1,1,1,-1,-1,-1}; int dy[]={1,-1,0,1,-1,0,1,-1}; const double inf = 1e30; double dist(double x,double y,double z) { return sqrt(x*x+y*y+z*z); } double a,b,c,d,e,f; double getz(double x,double y) { double A=c,B=d*y+e*x,C=a*x*x+b*y*y+f*x*y-1; double delta=B*B - 4*A*C; if(delta<0) return inf; double z1=(-B+sqrt(delta))/2/A; double z2=(-B-sqrt(delta))/2/A; if(z1*z1<z2*z2) return z1; else return z2; } double solve() { double step=1; double x=0,y=0,z; while(step>eps) { z=getz(x,y); for(int i=0;i<8;i++) { double nx=x+dx[i]*step; double ny=y+dy[i]*step; double nz=getz(nx,ny); if(nz>=inf) continue; if(dist(nx,ny,nz)<dist(x,y,z)) { x=nx,y=ny,z=nz; } } step*=0.99; } return dist(x,y,z); } int main() { while(cin>>a>>b>>c>>d>>e>>f) { printf("%.9f\n", solve()); } return 0; }