1. 程式人生 > 實用技巧 >hdu 6794 Tokitsukaze and Multiple 字首和思想+思維

hdu 6794 Tokitsukaze and Multiple 字首和思想+思維

題意:

t組輸入,給你一個長度為n的陣列,你每次可以從陣列中找到a[i]和a[i+1],然後用a[i]+a[i+1]這個新元素來覆蓋掉a[i]和a[i+1]的位置(1<=i<n),從而陣列長度也減去1

你可以進行任意次這樣的操作,輸出最後的陣列中有多少數,是p的倍數

題解:

給你一個a陣列的字首和陣列w,我們保證a[i]>=1,字首和w[i]都被p取餘過

假設i<j,那麼如果w[i]和w[j]相等,那也就是說(a[i+1]+a[i+2]+...+a[j])%p == 0,也就是說這一段是p的倍數

那麼我們就可以依靠這一點去做題

我們先判斷一下v[i]%p==0的點,然後依次這些點把原陣列分割,分別對每一段進行上面這樣的判斷

程式碼:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <math.h>
#include
<map> using namespace std; typedef long long ll; const int maxn = 3e5 + 5; ll v[maxn]; map<ll,ll>r; int main() { ll t; scanf("%lld",&t); while(t--) { ll n,p; r.clear(); scanf("%lld%lld",&n,&p); // ll vis[p+5]; // memset(vis,0,sizeof(vis));
for(ll i=1; i<=n; ++i) scanf("%lld",&v[i]),v[i]%=p; ll sum=0,mod=0; r[0]=1; for(ll i=1; i<=n; ++i) { if(v[i]==0) { mod=0; r.clear(); sum++; r[0]=1; } else { mod=(mod+v[i])%p; r[mod]++; if(r[mod]>=2) { mod=0; sum++; r.clear(); } r[0]=1; } } printf("%lld\n",sum); } return 0; }