1.
给定一个长度为N 模板字符串S,由小写字母组成;
定义一个同样长度为N 的字符串T 的价值为:T 中子串在字典序下大于S 中对
应下标子串的子串数量;
例如S =′ aabb′,T =′ bbbb′,那么T 的价值为7。
(区间[1, 1], [1, 2], [1, 3], [1, 4], [2, 2], [2, 3], [2, 4] 构成的子串,T 都对应大于S);
小D 想知道有多少个由小写字母构成的字符串T,它的价值恰好为K;
1 #pragma GCC optimize 2 2 #define mod 1000000007 3 #include<bits/stdc++.h> 4 using namespace std; 5 typedef long long int ll; 6 const int maxn=2E3+5; 7 int n,k; 8 ll f[maxn][maxn][3]; 9 char a[maxn]; 10 string str; 11 inline void add(ll&x,ll y) 12 { 13 x=(x+y)%mod; 14 } 15 inline void solve() 16 { 17 f[0][0][2]=1; 18 ll ans=0; 19 for(int i=1;i<=n;++i) 20 for(int j=0;j<=k;++j) 21 { 22 for(int q=i-1;j-(i-q)*(n-i+1)>=0&&q>=0;--q) 23 f[i][j][0]=(f[i][j][0]+(f[q][j-(i-q)*(n-i+1)][2]+f[q][j-(i-q)*(n-i+1)][0])*('z'-a[i])%mod)%mod; 24 f[i][j][1]=(f[i-1][j][0]+f[i-1][j][1]+f[i-1][j][2])%mod; 25 f[i][j][2]=(f[i-1][j][0]+f[i-1][j][1]+f[i-1][j][2])*(a[i]-'a')%mod; 26 } 27 cout<<(f[n][k][0]+f[n][k][1]+f[n][k][2])%mod<<endl; 28 } 29 int main() 30 { 31 freopen("string.in","r",stdin); 32 freopen("string.out","w",stdout); 33 ios::sync_with_stdio(false); 34 cin>>n>>k>>str; 35 for(int i=1;i<=n;++i) 36 a[i]=str[i-1]; 37 solve(); 38 return 0; 39 }
2.没调好。
3.CF627E Orchestra
写个链表就好了。注意update。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long int ll; 4 const int maxn=3E3+5; 5 int r,c,n,k; 6 int a[maxn][maxn],sum[maxn][maxn]; 7 vector<int>coin[maxn]; 8 ll ans; 9 int pre[maxn],nxt[maxn],cnt[maxn],have[maxn],R[maxn]; 10 inline int get(int l,int r,int u,int d) 11 { 12 return sum[d][r]-sum[d][l-1]-sum[u-1][r]+sum[u-1][l-1]; 13 } 14 inline void update(int y,int row,int x,ll&now) 15 { 16 while(R[y]!=c+1&&get(y,R[y],x,row)<k) 17 { 18 now-=have[y]*(c-R[y]+1); 19 R[y]=nxt[R[y]]; 20 now+=have[y]*(c-R[y]+1); 21 } 22 } 23 inline void solve(int x) 24 { 25 ll now=0; 26 int pos=1; 27 for(int i=1;i<=c;++i) 28 { 29 pre[i]=i-1; 30 nxt[i]=i+1; 31 while((pos<i||get(i,pos,x,r)<k)&&pos<=c) 32 ++pos; 33 R[i]=pos; 34 now+=c-pos+1; 35 have[i]=1; 36 cnt[i]=get(i,i,x,r); 37 } 38 for(int i=c;i>=1;--i) 39 if(cnt[i]==0) 40 { 41 pre[nxt[i]]=pre[i]; 42 nxt[pre[i]]=nxt[i]; 43 have[nxt[i]]+=have[i]; 44 } 45 ans+=now; 46 R[c+1]=c+1; 47 for(int row=r;row>x;--row) 48 { 49 for(int i=0;i<coin[row].size();++i) 50 { 51 int y=coin[row][i]; 52 --cnt[y]; 53 if(cnt[y]==0) 54 { 55 pre[nxt[y]]=pre[y]; 56 nxt[pre[y]]=nxt[y]; 57 have[nxt[y]]+=have[y]; 58 now-=have[y]*(R[nxt[y]]-R[y]); 59 for(int z=pre[y],tot=0;z&&tot<=k;z=pre[z],++tot) 60 update(z,row-1,x,now); 61 } 62 else 63 for(int z=y,tot=0;z&&tot<=k;z=pre[z],++tot) 64 update(z,row-1,x,now); 65 } 66 ans+=now; 67 } 68 } 69 int main() 70 { 71 ios::sync_with_stdio(false); 72 cin>>r>>c>>n>>k; 73 for(int i=1;i<=n;++i) 74 { 75 int x,y; 76 cin>>x>>y; 77 a[x][y]=1; 78 coin[x].push_back(y); 79 } 80 for(int i=1;i<=r;++i) 81 { 82 sort(coin[i].begin(),coin[i].end()); 83 reverse(coin[i].begin(),coin[i].end()); 84 } 85 for(int i=1;i<=r;++i) 86 for(int j=1;j<=c;++j) 87 sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]; 88 for(int i=1;i<=r;++i) 89 solve(i); 90 cout<<ans<<endl; 91 return 0; 92 }