Noip模拟62 2021.9.26
T1 Set
真就随机化拿了$90$??
不过还是有依据的,毕竟这道题出解的几率很大,随出答案的概率也极大
所以不妨打一个随机化
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 namespace AE86{ 5 inline int read(){ 6 int x=0,f=1;char ch=getchar(); 7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 9 }inline void write(int x,char opt='\n'){ 10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 12 for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 13 }using namespace AE86; 14 const int NN=1e6+5; 15 int n,a[NN],has[NN],sum; 16 inline void spj(){ 17 int sum=0; 18 for(int i=1;i<=n;i++) a[i]=read()%n; 19 for(int i=1;i<(1<<n);i++){ 20 sum=0; 21 for(int j=1;j<=n;j++) 22 if(i&(1<<j-1)) sum+=a[j]; 23 if(sum%n==0){ 24 write(__builtin_popcount(i)); 25 for(int j=1;j<=n;j++) if(i&(1<<j-1)) write(j,' '); 26 return; 27 } 28 } 29 puts("-1");return; 30 } 31 vector<int> pos; 32 namespace WSN{ 33 inline short main(){ 34 freopen("a.in","r",stdin); 35 freopen("a.out","w",stdout); 36 srand(time(0)^clock()); 37 n=read(); int yu; if(n<=20) {spj();return 0;} 38 for(int i=1;i<=n;i++){ 39 a[i]=read(); yu=a[i]%n; 40 if(!yu) {printf("1\n %lld\n",i);return 0;} 41 else if(has[n-yu]) {printf("2\n %lld %lld\n",has[n-yu],i);return 0;} 42 has[yu]=i; a[i]=yu; sum+=yu; 43 if(sum%n==0){ 44 write(i); for(int j=1;j<=i;j++) write(j,' '); 45 puts(""); return 0; 46 } 47 } 48 for(int i=1;i<=n/2+1;i++) if(has[n-i]&&has[i]){ 49 printf("2\n %lld %lld\n",has[i],has[n-i]); 50 return 0; 51 } 52 int tim=0,tot=50000000/n; 53 while(tim<tot){ 54 sum=0; pos.clear(); 55 for(int i=1;i<=n;i++) if(rand()&1){ 56 sum+=a[i]; pos.push_back(i); 57 if(sum%n==0){ 58 write(pos.size()); 59 for(int j=0;j<pos.size();j++) 60 write(pos[j],' '); 61 return 0; 62 } 63 } 64 ++tim; 65 } 66 puts("-1"); 67 return 0; 68 } 69 } 70 signed main(){return WSN::main();}
考虑正解,发现如果维护一个前缀和的余数,他的答案只能是$0~n-1$
但是一共有$n+1$个前缀和,那么必定有两个前缀和的余数是相等的,那么他们之间的所有数加起来就是答案
1 #include<bits/stdc++.h> 2 using namespace std; 3 namespace AE86{ 4 inline int read(){ 5 int x=0,f=1;char ch=getchar(); 6 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 7 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 8 }inline void write(int x,char opt='\n'){ 9 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 10 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 11 for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 12 }using namespace AE86; 13 const int NN=1e6+5; 14 int n,a[NN],has[NN],sum; 15 namespace WSN{ 16 inline short main(){ 17 freopen("a.in","r",stdin); 18 freopen("a.out","w",stdout); 19 srand(time(0)^clock()); 20 n=read(); 21 for(int i=1,x;i<=n;i++){ 22 x=read()%n; sum=(sum+x)%n; 23 if(!x) {printf("1\n %d\n",i);return 0;} 24 if(!sum||has[sum]){ 25 write(i-has[sum]); for(int j=has[sum]+1;j<=i;j++) write(j,' '); 26 puts(""); return 0; 27 } 28 if(!has[sum]) has[sum]=i; 29 } 30 puts("-1"); 31 return 0; 32 } 33 } 34 signed main(){return WSN::main();}
T2 Read
和$codeforces$里面一道题挺像,于是就只拿到了三十分,由于$n$太大了
正解与那道题做法不同,但是$fengwu$用那道题加上一个分块的思想切了这道题,超巨
正解只是多开两个变量$id,cnt$,考虑一种书要是超过$\frac{n}{2}+1$那么答案必定为$0$
那么我们只需要找到 最多书的个数 减去 剩下的书个数$+1$ 就是答案
然后用$id,cnt$维护一波最值即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 namespace AE86{ 4 inline int read(){ 5 int x=0,f=1;char ch=getchar(); 6 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 7 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 8 }inline void write(int x,char opt='\n'){ 9 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 10 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 11 for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 12 }using namespace AE86; 13 int M,K,C[1005],X[1005],Y[1005],Z[1005],S,last,id,cnt,N; 14 namespace WSN{ 15 inline short main(){ 16 freopen("b.in","r",stdin); 17 freopen("b.out","w",stdout); 18 M=read(); K=read(); 19 for(int i=1;i<=M;i++) C[i]=read(),N+=C[i]; 20 for(int i=1;i<=M;i++) X[i]=read(); 21 for(int i=1;i<=M;i++) Y[i]=read(); 22 for(int i=1;i<=M;i++) Z[i]=read(); 23 S=(1<<K)-1; 24 for(int i=1;i<=M;i++){ 25 last=X[i]; 26 if(!cnt) id=last,cnt=1; 27 else if(id==last) ++cnt; 28 else --cnt; 29 for(int j=1;j<C[i];j++){ 30 last=(last*Y[i]+Z[i])&S; 31 if(!cnt) id=last,cnt=1; 32 else if(id==last) ++cnt; 33 else --cnt; 34 } 35 } 36 if(cnt<=0) return puts("0"),0; cnt=0; 37 for(int i=1;i<=M;i++){ 38 last=X[i]; 39 if(last==id) ++cnt; 40 for(int j=1;j<C[i];j++){ 41 last=(last*Y[i]+Z[i])&S; 42 if(last==id) ++cnt; 43 } 44 } 45 write(max(cnt*2-N-1,0)); 46 return 0; 47 } 48 } 49 signed main(){return WSN::main();}
T3 题目交流通道
考场上以为是有向图,觉得第一个点的$30$分复杂度$O(5^{12})$会炸
但是是无向图所以只有$O(5^6)$,所以我就没打暴力,所以就从$rk8->rk10$
是个人都拿了这题的三十分。。。。
场上以为是矩阵快速幂的变形,后来才发现不对劲
按照题解上的打一个并查集,然后做就可以,容斥考虑两个团之间的点的强制选择问题
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 namespace AE86{ 5 inline int read(){ 6 int x=0,f=1;char ch=getchar(); 7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 9 }inline void write(int x,char opt='\n'){ 10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 12 for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 13 }using namespace AE86; 14 const int mod=998244353,NN=401; 15 16 int n,k,d[NN][NN],C[NN][NN],ans=1; 17 int fa[NN],siz[NN]; bool vis[NN]; 18 int num,FA[NN]; 19 pair<int,int> dis[NN][NN]; vector<int> son[NN]; 20 bool inq[NN][NN]; 21 int g[NN],f[NN]; 22 23 inline int getfa(int x){return fa[x]=(fa[x]==x?x:getfa(fa[x]));} 24 inline int qmo(int a,int b,int ans=1){ 25 int c=mod; while(b){ 26 if(b&1) ans=ans*a%c; 27 b>>=1; a=a*a%c; 28 } return ans; 29 } 30 31 namespace WSN{ 32 inline short main(){ 33 freopen("c.in","r",stdin); 34 freopen("c.out","w",stdout); 35 n=read(); k=read(); C[0][0]=1; 36 for(int i=1;i<=n;i++){ C[i][0]=C[i][i]=1; 37 for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; 38 } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=read(); 39 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ 40 if(d[i][j]!=d[j][i]) return puts("0"),0; 41 if(d[i][i]!=0) return puts("0"),0; if(d[i][j]>k) return puts("0"),0; 42 } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) 43 if(i!=j && i!=k && j!=k) if(d[i][j]>d[i][k]+d[k][j]) return puts("0"),0; 44 for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1; 45 for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(d[i][j]==0){ 46 int x=getfa(i),y=getfa(j); if(x!=y) fa[y]=x,siz[x]+=siz[y]; 47 } for(int i=1;i<=n;i++) 48 if(!vis[getfa(i)]) FA[++num]=getfa(i),vis[getfa(i)]=1,son[getfa(i)].push_back(getfa(i)); 49 else son[getfa(i)].push_back(i); 50 for(int i=1;i<num;i++) for(int j=i+1;j<=num;j++){ 51 int f=FA[i],ff=FA[j]; 52 dis[f][ff]=dis[ff][f]=make_pair(d[son[f][0]][son[ff][0]],siz[f]*siz[ff]); 53 }for(int k=1;k<=num;k++) for(int i=1;i<=num;i++) 54 for(int j=1;j<=num;j++) if(i!=j && i!=k && j!=k) 55 if(dis[FA[i]][FA[j]].first==dis[FA[i]][FA[k]].first+dis[FA[k]][FA[j]].first) 56 inq[FA[i]][FA[j]]=inq[FA[j]][FA[i]]=1; 57 for(int i=1;i<num;i++) for(int j=i+1;j<=num;j++){ 58 int f=FA[i],ff=FA[j]; 59 if(inq[f][ff]) ans=ans*qmo(k-dis[f][ff].first+1,dis[f][ff].second)%mod; 60 else ans=ans*(qmo(k-dis[f][ff].first+1,dis[f][ff].second)-qmo(k-dis[f][ff].first,dis[f][ff].second)+mod)%mod; 61 } for(int i=1;i<=n;i++) g[i]=qmo(k+1,C[i][2]); 62 for(int i=1;i<=n;i++){ 63 int tmp=0; 64 for(int j=1;j<=i-1;j++) 65 tmp=(tmp+f[j]*g[i-j]%mod*C[i-1][j-1]%mod*qmo(k,j*(i-j))%mod)%mod; 66 f[i]=(g[i]-tmp+mod)%mod; 67 } for(int i=1;i<=num;i++) ans=ans*f[siz[FA[i]]]%mod; write(ans); 68 return 0; 69 } 70 } 71 signed main(){return WSN::main();}
(测试点非常水,大样例没过就$A$了,不过放心这是真$AC$代码)
T4 题目难度提升
没时间了
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 namespace AE86{ 5 inline int read(){ 6 int x=0,f=1;char ch=getchar(); 7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 9 }inline void write(int x,char opt='\n'){ 10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 12 for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 13 }using namespace AE86; 14 const int NN=1e6+5,inf=1e10; 15 int n,ans[NN],mid,p,q,s[NN]; 16 bool vis[NN]; 17 multiset<int> st; 18 priority_queue<int> a,b; 19 inline void push(int s){ 20 if(!a.size() || s<=a.top()) a.push(s); 21 else b.push(-s); 22 if(a.size()<b.size()) a.push(-b.top()),b.pop(); 23 if(a.size()>b.size()+1) b.push(-a.top()),a.pop(); 24 } 25 namespace WSN{ 26 inline short main(){ 27 freopen("d.in","r",stdin); 28 freopen("d.out","w",stdout); 29 n=read(); mid=1+n>>1; 30 for(int i=1;i<=n;i++) s[i]=read(); 31 sort(s+1,s+n+1); 32 if(s[mid]==s[mid+1]){ 33 while(s[mid]==s[mid+1] && mid<n) ++mid; 34 write(s[mid],' '); p=mid-1; q=n; 35 while(p || mid<q){ 36 if(p) write(s[p--],' '); 37 if(mid<q) write(s[q--],' '); 38 } return 0; 39 } 40 while(s[mid]!=s[mid-1] && mid>1) --mid; 41 write(s[mid],' '); vis[mid]=1; p=mid-1; q=n; 42 while(p && mid<q){ 43 write(s[p],' '); vis[p--]=1; 44 write(s[q],' '); vis[q--]=1; 45 } 46 for(int i=1;i<=n;i++) if(vis[i]) push(s[i]);else st.insert(s[i]); 47 while(st.size()){ 48 p=*st.begin(); 49 if(a.size()==b.size()){ 50 if(p>=-b.top()) q=*--st.end(); 51 else q=*st.begin(); 52 } 53 else{ 54 if(!b.empty() && p*2>=a.top()-b.top()) q=*--st.end(); 55 else q=*--st.upper_bound(p*2-a.top()); 56 } 57 write(q,' '); push(q); st.erase(st.find(q)); 58 } 59 return 0; 60 } 61 } 62 signed main(){return WSN::main();}