1. 程式人生 > 實用技巧 >Educational Codeforces Round 93 (Rated for Div. 2) C. Good Subarrays

Educational Codeforces Round 93 (Rated for Div. 2) C. Good Subarrays

題目連結:https://codeforc.es/contest/1398/submission/89983348

題意:給定一個序列由0~9組成 定義 好子序列 為 長度等於其元素和 的序列,問有多少個好子序列

思路:因為要o n 過完,所以先考慮邊跑邊處理, 也就是走到某一個點的時候要能知道前面有多少是滿足的

那麼考慮用map和字首和來記錄前面的狀態 然後就考慮 後面要如何累加前面的

但是一個好子序列的和是不確定的,所以必須要通過處理使得確定下來才能記錄, 考慮把每個數都-1 那麼和為0的即是滿足要求的

也就是現在只需要找出序列中哪些段和為0即可, 那麼維護一個字首和,sum 為0的時候滿足,當sum不為0的時候 就要考慮前面有沒有和這個sum一樣的數

如果有的話,這兩個字首和相減 也是一段為0的子序列

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=1e5+10;
 7 const int mod=1e9+7;
 8 char s[maxn];
 9 
10 
11 
12 int main()
13 {
14     ios::sync_with_stdio(false);
15
cin.tie(0); 16 int t; 17 cin>>t; 18 while(t--) 19 { 20 int n; 21 cin>>n; 22 cin>>(s+1); 23 ll ans=0; 24 map<ll,ll>mp; 25 ll sum=0; 26 for(int i=1;i<=n;i++) 27 { 28 int x=s[i]-'0'-1;
29 sum+=x; 30 if(sum==0) 31 ans++; 32 ans+=mp[sum]; 33 mp[sum]++; 34 } 35 cout<<ans<<'\n'; 36 } 37 38 39 40 41 }
View Code

也可以根據題意推得公式 sum[r]-sum[l-1]=r-l+1 等價於 sum[r]-r=sum[l-1]-(l-1) 那麼也就是去找每個座標之前有多少個sum-i 是一樣的即可

根據實際意義 l=1的時候也是可以滿足的 sum[i]-i==0 時額外+1即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=1e5+10;
 7 const int mod=1e9+7;
 8 char s[maxn];
 9 
10 
11 
12 int main()
13 {
14     ios::sync_with_stdio(false);
15     cin.tie(0);
16     int t;
17     cin>>t;
18     while(t--)
19     {
20         int n;
21         cin>>n;
22         cin>>(s+1);
23         ll ans=0;
24         map<ll,ll>mp;
25         ll sum=0;
26         for(int i=1;i<=n;i++)
27         {
28             int x=s[i]-'0';
29             sum+=x;
30             ll temp=sum-i;
31             if(temp==0)
32                 ans++;
33             ans+=mp[temp];
34             mp[temp]++;
35         }
36         cout<<ans<<'\n';
37     }
38 
39 
40 
41 
42 }
View Code