[校内训练20_06_04]ABC

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 }
View Code

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 }
View Code
原文地址:https://www.cnblogs.com/GreenDuck/p/13085027.html