题解之前
今天还行啊。
Set
肯定要取模。
开始还在想vector这种操作,后来一个dalao发现一定有解,然后有发现一定有一种答案是连续的一段区间,于是就切掉了。
看了题解才发现我们只是运气好。
前缀和如果有n取值,就选%n=0的那一个,不然至多只剩n-1个取值,然而又有n个前缀和。
所以必然有两个相等,输出这之间的下标即可。
#include<cstdio> #include<cctype> #include<cstring> #define FN "set" const int maxn=1e6+5; inline int read() { int x;char ch;while(!isdigit(ch=getchar())); for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); return x; } int a[maxn],mod[maxn]; int main() { freopen(FN".in","r",stdin); freopen(FN".out","w",stdout); int n;scanf("%d",&n); for(int i=1;i<=n;i++) { a[i]=read()%n; } memset(mod,-1,sizeof(mod)); int sum=0; for(int i=1;i<=n;i++) { sum=(sum+a[i])%n; if(!a[i]) { printf("1\n%d",i); return 0; } if(~mod[sum]) { printf("%d\n",i-mod[sum]); for(int j=mod[sum]+1;j<=i;j++) printf("%d%c",j,(j==i)?'\n':' '); return 0; } mod[sum]=i; } printf("-1"); return 0; }
Read
并不知道subtask是什么,因为我A了。
想要每天读书种类不同,就要求每一种书不超过其他书总和+1,于是找出有没有这么一本书就行了。
由于空间限制,不存A数组,按照那个跑两遍,第一遍找最大值是谁,第二遍找最大值出现了几次,在进行比对即可。
#include<bits/stdc++.h> #define FN "read" const int maxm=1000+5; int count[maxm],X[maxm],Y[maxm],Z[maxm]; inline int read() { int x;char ch;while(!isdigit(ch=getchar())); for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); return x; } int main() { freopen(FN".in","r",stdin); freopen(FN".out","w",stdout); int M=read(),K=read(),N=0,S=(1<<K)-1; for(int i=1;i<=M;++i) count[i]=read(); for(int i=1;i<=M;++i) X[i]=read(); for(int i=1;i<=M;++i) Y[i]=read(); for(int i=1;i<=M;++i) Z[i]=read(); int whi=-1,num=0; for(int i=1;i<=M;++i) { N=N+1; int temp=X[i]; if(!num) whi=temp; if(temp==whi) ++num; else --num; long long last=X[i]; for (int j=1;j<count[i];++j) { last=(1LL*last*Y[i]+Z[i])&S; N=N+1; temp=last; if(!num) whi=temp; if(temp==whi) ++num; else --num; } } num=0; for(int i=1;i<=M;++i) { int temp=X[i]; if(temp==whi) ++num; long long last=X[i]; for (int j=1;j<count[i];++j) { last=(1LL*last*Y[i]+Z[i])&S; temp=last; if(temp==whi) ++num; } } int ans; if(num<=(N+1)/2) ans=0; else ans=num-N+num-1; printf("%d",ans); return 0; }
race
trie树,还在抢救中~
来源:https://www.cnblogs.com/LoLiK/p/9692727.html