tj:我們發現,每一次走過的步長都是k,設當前走的步數是x,走到了一個白條
那麼,每一次走就是把所有黑條都向前移k位,我們可以考慮把所有黑條的左邊界不斷的向前移動k,直到下一次移動時,其左邊界小於0,則我們進行的操作實際上是把邊界模k
這樣子,我們得到的所有黑條就是介於[0,k-1]中的。當然有些黑條由於跨過了1個分界線而導致變成2個區間
最後判斷有沒有連續的長度大於等於s的區間即可,注意,整個區間是環形的,要加上最後一條黑條和第一條黑條對答案的影響
注意無解的情況:當有黑條的長度大於k或者k<s都無解
代碼:
#include<bits/stdc++.h>
using namespace std;
struct no{
int x,y;
bool operator <(const no &rhs)const{
return x<rhs.x||x==rhs.x&&y<rhs.y;
}
}t[1000010];
int a[1000010],ct,s,k,n;
int main(){
freopen("emotional.in","r",stdin);
freopen("emotional.out","w",stdout);
int T;
scanf("%d",&T);
while(T--){
int ok=0;
scanf("%d%d%d",&s,&k,&n);
ct=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
if((i&1)&&k<=a[i]&&!ok){
printf("NIE\n");
ok=1;
continue;
}
if(ok)continue;
int las=0;
for(int i=1;i<=n;i++){
las+=a[i];
if(i&1){
int l=las-a[i],r=las-1;
las%=k;
if((l/k)<(r/k)){
t[++ct]=(no){0,r%k};
t[++ct]=(no){l%k,k-1};
}
else t[++ct]=(no){l%k,r%k};
}
}
if(s>k){
printf("NIE\n");
continue;
}
sort(t+1,t+ct+1);
las=-1;
int r=-1e9;
for(int i=1;i<=ct;i++){
r=max(r,t[i].x-las-1);
las=max(las,t[i].y);
}
r=max(r,t[1].x+k-1-las);
if(r>=s)printf("TAK\n");
else printf("NIE\n");
}
}